std::__non_rtti_object bei dynamic_cast<...>
-
Hallo Freunde,
ich habe folgende Vererbungsstruktur:
Actor
- Structure
* Cannon
- MovingUnit
* Missle
+ Bullet
+ Laser
+ Rocket
* Unit
+ Enemy
+ ...Der Destructor von Actor und auch den folgenden Classen ist virtual, damit ich auch einen dynamic_cast machen kann.
Ich nutze Box2D für Collision Detection.
Sobald eine Kollision auftaucht, kann ich über ein "contact pointer" mir die zwei Objekte holen, die Kollidiert sind. Diese haben einen Pointer UserData inne, welcher jeweils auf das entsprechende Objekt zeigt, also z.b. Bullet, Laser oder Enemy.Dieses UserData ist vom Typ (void*), wenn ich dieses nun in ein "Actor" casten möchte, ist das bei Bullet und Cannon kein Problem, nur wenn ich es ein Enemy ist, dann kommt obiger Fehler und mein Programm stützt ab.
Was könnte zu diesem Fehler noch geführt haben?
Ich habe gelesen, dass wenn nicht mindesten eine virtual Methode dabei ist, dieser fehler bei einem dynamic_cast ausgelöst wird, aber dies ist nun ausgeschlossen.void Collider::BeginContact(b2Contact* contact) { b2Fixture* A = contact->GetFixtureA(); b2Fixture* B = contact->GetFixtureB(); Actor* actorA = (Actor*)A->GetBody()->GetUserData(); Actor* actorB = (Actor*)B->GetBody()->GetUserData(); if(actorA && actorB){ MovingUnit* m1 = dynamic_cast<MovingUnit*>(actorA); MovingUnit* m2 = dynamic_cast<MovingUnit*>(actorB); std::cout << "ActorA " << actorA->GetActorTyp() << " / ActorB " << actorB->GetActorTyp() << std::endl; } }Gruß
Ani
-
Dann wird der Zeiger wohl auf gar kein gültiges Objekt zeigen:
http://msdn.microsoft.com/en-us/library/fyf39xec(VS.80).aspxIf the pointer does not point to a valid object, a __non_rtti_object exception is thrown, indicating an attempt to analyze the RTTI that triggered a fault (like access violation), because the object is somehow invalid (bad pointer or the code wasn't compiled with /GR).
Das du ein Problem hast ist auch nicht so verwunderlich. Jede Art von dynamic_cast und reinterpret_cast deutet auf Designfehler hin. Du hast gleich beides und zwar mehrmals. Insbesondere bei void*- und reinterpret_cast-Spielereien setzt man sämtliche Schutzfunktionen des Typensystems außer Kraft und sagt dem Compiler, dass er gefälligst das Maul halten soll, auch wenn er Fehler zu finden meint, weil man es selber besser weiß. Aber du weißt es nicht besser, im Gegenteil, ich vermute du hast dieses Design aus Unwissen gewählt. Liege ich da richtig?
Versuche daher besser dein Programm nochmal vollständig umzukrempeln, so dass du nirgendwo dynamic_cast, reinterpret_cast oder void* benötigst. dynamic_cast deutet auf falsch benutzte Polymorphie hin. Deine riesige Vererbungshierarchie ist auch sehr verdächtig. Vererbung hat man sowieso eher selten und du hast gleich mehrere Ebenen an Verwandschaftsbeziehungen. reinterpret_cast und void* deuten auf falsch gemachte Abstraktion hin. Wähle die passenden Typen. Programmiere generische Funktionen mittels Templates, niemals mit void*.
-
Box2D verwendet eben void* für Userdata, da kann er nicht viel dafür.
Vermutung: Du hast als Userdata einen Zeiger auf ein Stackobjekt gesetzt, das zum Zeitpunkt der Kollision ungültig ist?
-
Wie von Ethon bereits erwähnt kann ich für das void* nicht viel...
Eigentlich düfte das Objekt nicht ungültig sein.
Wie man evtl. erkennt ist das ganze ein Spiel, die Enemies fliegen durch die gegend und der Spieler muss sie abschießen.Bei der Initialisierung der Objekte werden jeweils die UserDaten zugeordnet, und die Kollion kann da nocht nicht auftreten.
-
"eigentlich sollte nicht" ist nicht "ist". Eigentlich sollte die Welt perfekt sein, ist sie aber nicht.
Der Computer gibt dir eine Fehlermeldung. Es ist genau dokumentiert, wann die Fehlermeldung auftritt. Anscheinend ist dein "eigentlich nicht" nicht der Fall oder es tritt eine der anderen möglichen Ursachen für die Fehlermeldung auf (siehe Link). Ein ungültiger Zeiger ist der naheliegendste, da du hier tatsächlich mit Zeigern hantierst, bezüglich deren Gültigkeit wir uns auf dein Wort verlassen müssen. Und da vertraue ich erfahrungsgemäß doch eher dem Computer als dem Programmierer.