2016-07-01 13 views
0

Also ich versuche, einen Ressourcenlader und Manager zu schreiben (Ja, ich weiß von Thor, das ist nur ein "Lernprojekt".) Und ich habe angefangen, mit Gewerkschaften zu experimentieren, nicht etwas Ich benutze sehr oft. Ich habe eine Klasse (wie im Code unten gesehen) namens resource erstellt, die eine Union hat, die eine Textur/Schriftart enthält. Die Textur wird korrekt geladen. die Schrift löst jedoch eine Zugriffsverletzung ausRessource Union wirft Zugriffsverletzung für Schriftarten in SFML

Exception thrown at 0x00C5DBE0 in Project.exe: 0xC0000005: Access violation reading location 0x00000004. 

Das folgende ist mein vollständiges und minimales Beispiel. EDIT :: Aktualisierter Code löst das Problem. Evan erklärte unten, dass dies der Fall ist, weil nur das erste Element in einer Union standardmäßig konstruiert ist.

#include <SFML/Graphics.hpp> 

class Resource 
{ 
public: 
    union 
    { 
     sf::Texture t; 
     sf::Font f; 
    }; 

    Resource(sf::Font font = sf::Font()) : f(font) 
    {           } 

    ~Resource() 
    {   } 
}; 

int main() 
{ 
    Resource font; 
    Resource tex; 

    if (!tex.t.loadFromFile("player.png")) {} //! Works great! 
     //doError 

    if (!font.f.loadFromFile("blocks.ttf")) {} //! Throws access violation. 
     //doError 

    return 0; 
} 
+0

Ohne die Definitionen von sf durchgeführt werden muß :: Textur und sf :: Font es ist unmöglich zu sagen, was passiert, aber ich würde vermuten, dass f nicht richtig konstruiert wurde. – evan

+0

Das sind Teil der SFML-Bibliothek. Es kann tatsächlich mit dem Standardkonstruktor konstruiert werden, wie ich oben getan habe. – Reborn

+0

Haben Sie versucht zu sehen, ob das Problem die SFML-Klassen oder Ihre Verwendung von ihnen ist? Ich habe versucht, Ihr Problem mit einem 'string' und' vector' zu lösen und hatte selbst Probleme. Wenn Sie das Problem mit STL neu erstellen können, können Sie eine größere Zielgruppe erreichen. –

Antwort

2

Ich würde vermuten, dass f ist unitalisiert. Die Speicherbereiche der Mitglieder einer Union überschneiden sich, und wenn Sie dem Compiler nichts anderes mitteilen, wird nur das erste Mitglied initialisiert.

Sie können sie entweder in einem Konstruktor selbst initialisieren oder indem Sie placement new verwenden.

new (&f) sf::Font; 

Außerdem wird die Vereinigung zerstörende Probleme verursachen, da der Compiler nicht weiß, welches Mitglied zu zerstören, und es wird manuell wie

f.~sf::Font(); 
+0

Wo würde ich 'new (& f) sf :: Font;'? In einem Konstruktor oder in der Union selbst? Oder in der Hauptfunktion? – Reborn

+1

In 'main' vor' font.f.loadF ... 'add' new (& font.f) sf :: Font; ' – evan