Segmentation fault beim Deleten eines Pointers
-
@daniel sagte in Segmentation fault beim Deleten eines Pointers:
Was passiert denn, wenn ich innerhalb eines for (auto& : states) ein Element lösche, dieses aber noch im Rest der Schleife verwendet wird?
Das tut man nicht ergibt undefiniertes Verhalten, weil begin und end nur einmalig am Anfang abgefragt werden und du somit über das Ende hinaus loopen würdest.
Aber welche deiner Funktionen isUpdating, isDrawing, handleEvents, update, draw tut das denn? Keine davon sieht so aus, als kennte sie den activeStates-vector und könnte also daraus was löschen.
Und wie kann es sein, dass der Destruktor des States nicht aufgerufen wird, wenn der Pointer dazu gelöscht wird?
Du hast @manni66 s Frage nach dem virtuellen Destruktor noch nicht beantwortet.
Ansonsten: Glaskugel.
-
@manni66 Nein, es gibt keinen virtuellen Destruktor. Und der Main Loop wird in der StateMachine ausgeführt, die den vector besitzt. In der update Funktion irgendeines States ruft dieser die popState() Methode der StateMachine auf und übergibt sich selbst als pointer. Die StateMachine löscht den Pointer dann und entfernt das zugehörige Element aus dem Vector. Dann, wenn update() des States abgeschlossen ist, wird draw() aufgerufen, nur halt mit dem invaliden Pointer. Warum ruft
delete *it
nicht den Destruktor des States auf?
-
@daniel sagte in Segmentation fault beim Deleten eines Pointers:
Warum ruft delete *it nicht den Destruktor des States auf?
@daniel sagte in Segmentation fault beim Deleten eines Pointers:
Nein, es gibt keinen virtuellen Destruktor.
-
Das hast du dir doch selbst beantwortet:
@daniel sagte in Segmentation fault beim Deleten eines Pointers:Nein, es gibt keinen virtuellen Destruktor.
So wird nur der Destruktor des Basisklassenobjektes (also
~State()
) aufgerufen.Aber selbst damit darfst du innerhalb der Schleife keine Elemente aus dem Vector löschen.
Du könntest sie als "gelöscht" markieren und nachher dann aus dem Vector löschen (aber auch dort nicht per "for-range"-Schleife!).
-
@Th69 Aber warum sollte ich einen Destruktor für die Basisklasse brauchen? Wenn ich die davon erbende Klasse lösche, wird doch ein Default Konstruktor für die Basisklasse erstellt, oder nicht? Und es wird ja auch nicht der Destruktor der erbenden Klasse aufgerufen.
-
@daniel Dein State soll einen virtuellen Destruktor haben, damit die Klasse weiß, dass sie den Destruktor von der abgeleiteten Klasse aufrufen soll. Es gilt die Regel: Wenn du von einer Klasse erben möchtest, mache den Destruktor virtual!
-
Dann lies dich mal über virtuelle Destruktoren ein, z.B. Destructors ("Virtual destructors") oder Virtual Destructor.
-
Alles klar ich werde mich da mal genauer einlesen. Mit dem virtuellen Destruktor und der validState Flag funktioniert es. Vielen Dank für die Hilfe von allen!