Fehler bei STL-map als Klassenelement
-
Das LP am Anfang deutet auf einen Pointer hin. Sollte also kopierbar sein.
-
Kahino schrieb:
Wenn ich jedoch mit dem Debugger schrittweise durch das Programm gehe, zeigt er mir als Fehlerquelle eine Stelle in der Includedatei "map".
Kurze Frage: Welche genau?
-
Also kopierbar sollte das Ding sein(Ist ein Zeiger, wenn mich nicht alles täuscht verbirgt sich hinter LPDIRECT3DTEXTURE9 IDirect3DTexture9*), schließlich habe ich diese Variable in einem anderen Projekt ja auch auf genau die Selbe Weise verwendet.
Wenn ich schrittweise durch den Debugger gehe, wird der Fehler in Zeile 167 der Map-Datei angezeigt
mapped_type& operator[](const key_type& _Keyval) /*diese hier*/ { // find element matching _Keyval or insert with default mapped iterator _Where = this->lower_bound(_Keyval); if (_Where == this->end() || this->comp(_Keyval, this->_Key(_Where._Mynode()))) _Where = this->insert(_Where, value_type(_Keyval, mapped_type())); return ((*_Where).second); } };Doch weiß ich damit leider nichts anzufangen
Gehe ich weiter, zeigt er eine zeile tiefer den nächsten Fehler.
Gehe ich noch weiter, landet der debugger wie ich gerade sehe in der Datei "xtree" Zeile 1170.Ab diesen Punkt geht es dan nicht mehr weiter:
Unbehandelte Ausnahme bei 0x00402090 in Memory_04.exe: 0xC0000005: Zugriffsverletzung beim Lesen an Position 0x00000004.
_Nodeptr _Lbound(const key_type& _Keyval) const { // find leftmost node not less than _Keyval /*diese hier*/ _Nodeptr _Pnode = _Root(); _Nodeptr _Wherenode = _Myhead; // end() if search failsAber auch damit weiß ich nichts anzufangen.
Was mich hier ja am meisten verwundert ist, dass ich exakt das Selbe in einem anderen Proekt erfolgreich machen konnte, ohne solche Fehler.Und ich habe jetzt extra ncoh einmal nachgeschaut.
Die Include-datei map ist eingebunden, sonst gäbe es wohl auch schon kompillierfehler.
Die headerdatei der entsprechenden Klasse ist auch in die cpp-datei der entsprechenden Klasse eingebunden.
-
Was hast du denn vorher mit der map gemacht? Der Fehler sieht für mich danach aus, als ob du irgendwelche internen Datenstrukturen pulverisiert hättest.
-
Ok.
Dieser Map Daten hinzuzufügen ist das erste was mit dieser Map passiert.Doch hatte ich es versäumt zu erwähnen, dass die entsprechende Klasse auf Grund anderer Anforderungen im Gegensatz zur Selben Klasse im vorigen Projekt (wo ja alles geklappt hatte) eine Singleton Klasse ist.
Ich konnte mir einfach nicht vorstellen, dass dies der Fehler sein könnte, doch wie sich durch ein wenig experimentieren herausstellte, ist dies die Ursache.
Doch werde ich doch wohl irgendwie eine map in einem statischen Objekt verwenden können oder?Ok, die statische Version sah ungefäh so aus:
class staticversion { (Destruktor) static staticversion& Instance() { static staticversion& blub = staticversion::staticversion(); return blub; } ... AddTexture( Unter anderem std::wstring name); ... private: (Konstruktor/Kopierkonstruktor ... std::map<std::wstring, LPDIRECT3DDEVICE9> Texturen; ... };Wenn ich die Instanziierungsfunktion weg mache und die Konstruktoren öffentlich mache klappt alles.
Aber was hat das denn mit der Map zu tun?
Das kann der map doch egal sein ob das Objekt das sie enthält nun statisch ist oder nicht oder?
Oder anders, wie kommt es bei diesem Vorgehen, dass innere Datenstrukturen zerstört werden?-----
E D I T
-----
Es hat sich was neues ergeben.
Wenn ich:static staticversion& Instance() { static staticversion& blub = staticversion::staticversion(); return blub; }durch
static staticversion& Instance() { static staticversion blub = staticversion::staticversion(); return blub; }ersetze klappt das alles ebenfalls.
Wie es scheint erstelle ich in der ersten Version zwar eine statische Referenz, der jedoch ein nicht statisches Objekt als intialisierer übergeben wird, das am Ende der Anweisung schließlich zerstört wird.
So würde ich es mir erklären.
Doch da stellt sich mir wieder die Frage, wieso das Selbe Vorgehen bei Klassen funktioniert die keine map verwenden?
-
Kahino schrieb:
static staticversion& Instance() { static staticversion& blub = staticversion::staticversion(); return blub; }durch
static staticversion& Instance() { static staticversion blub = staticversion::staticversion(); return blub; }Das ist beides Nonsens.
static staticversion& Instance() { static staticversion blub; return blub; }Das Problem mit der Map könnte unter Umständen damit zusammenhängen, dass sie noch nicht konstruiert wurde. Das passiert bei globalen Objekten, die andere globale Objekte in anderen Compile Units referenzieren. Die Konstruktionsreihenfolge ist dann nicht definiert.
-
Kahino schrieb:
static staticversion& Instance() { static staticversion& blub = staticversion::staticversion(); return blub; }Da haben wir schon den Übeltäter: du legst eine Referenz auf ein temporäres Objekt an - und letzteres wird direkt am Semikolon wieder pulverisiert. Das bedeutet, blub glaubt zwar, auf ein 'staticversion'-Objekt zu zeigen, aber in Wirklichkeit zeigt es auf einen Haufen Datenmüll (und das erklärt auch die anschließende Zugriffsverletzung).
-
Wenn du es nicht kopieren willst und auch noch dynamisch (also zu einer unbestimmten Zeit) erstellen willst, solltest du auch den Heap benutzen:
class staticversion { static staticversion& Instance() { if(blub == NULL) blub = new staticversion(); return *blub; // dereferenziert zurück geben, wenns by-Ref sein soll } private: static staticversion *blub; std::map<std::wstring, LPDIRECT3DDEVICE9> Texturen; };Wo hast du überhaupt die ursprüngliche Implementierung her? Hat ja die hälfte gefehlt. Außerdem ist Singlton ein Pattern, das man nicht einfach so verwenden sollte. Haben manche schon ganze Bücher drüber geschrieben.

-
Da haben wir schon den Übeltäter: du legst eine Referenz auf ein temporäres Objekt an - und letzteres wird direkt am Semikolon wieder pulverisiert.
Diese Vermutung hatte ich im Edit-Bereich meines letzten Posts auch schon geäußért, doch seltsam ist dabei, dass ich in einem früheren Projekt eine Singleton Klasse (erstellt nach dem gleichen Prinzip wie diesem(falschen) hier) hatte, die ich auch verwenden konnte, obwohl die entsprechenden Funktionen auf Daten zugreifen die beim zerstören des Objekts nicht mehr hätten vorhanden sein dürfen(geht hier um einen Zeiger, der müsste ja dann beim zerstören des Objekts die Adresse verlieren und beim aufruf dieses Elements einen Fehler verursachen oder?)
In diesem Projekt habe ich diese Klasse testweise wieder zu einer singleton umgemodelt, nach dem selben (falschen) Prinzip und es funktionierte Tadellos.
Wenn du es nicht kopieren willst und auch noch dynamisch (also zu einer unbestimmten Zeit) erstellen willst, solltest du auch den Heap benutzen
Danke für den Hinweise.
Wo hast du überhaupt die ursprüngliche Implementierung her? Hat ja die hälfte gefehlt. Außerdem ist Singlton ein Pattern, das man nicht einfach so verwenden sollte. Haben manche schon ganze Bücher drüber geschrieben.
Wo ich die Implementierung her habe?
Ich schätze mal du meinst wohl die Implementierung der Instanziierungsfunktion.
Die hab ich nirgends her.
Hab mal gelesen, dass es sowas wie eine Singletonklasse gibt, die man überall verwenden kann und von der es nur eine Instanz zu geben hat.
Vorraussetzung dafür ist(so hab ichs gelesen), dass die Klasse eine statische Instanziierungsfunktion hat die ein statisches Objekt zurückliefert, mehr weiß ich nicht darüber.Oder was meinst du genau mit Implementierung?
Falls du die Die Funktion zum hinzufügen der Textur meinst, da sollten die die drei Punkte andeuten, dass da was fehlt.
-
Kahino schrieb:
Da haben wir schon den Übeltäter: du legst eine Referenz auf ein temporäres Objekt an - und letzteres wird direkt am Semikolon wieder pulverisiert.
Diese Vermutung hatte ich im Edit-Bereich meines letzten Posts auch schon geäußért, doch seltsam ist dabei, dass ich in einem früheren Projekt eine Singleton Klasse (erstellt nach dem gleichen Prinzip wie diesem(falschen) hier) hatte, die ich auch verwenden konnte, obwohl die entsprechenden Funktionen auf Daten zugreifen die beim zerstören des Objekts nicht mehr hätten vorhanden sein dürfen(geht hier um einen Zeiger, der müsste ja dann beim zerstören des Objekts die Adresse verlieren und beim aufruf dieses Elements einen Fehler verursachen oder?)
Sowas nennt sich dann "undefiniertes Verhalten" - vermutlich hattest du beim letzten Mal Glück, daß die Objektdaten des Singleton noch nicht durch andere Stack-Operationen überschrieben wurden.
-
Ok, danke jedenfalls für eure Hilfe.
Kann das map-Problem also nun abhaken.cu