list literator not decrementable
-
Hallo,
ich habe in Folge eines Tutorials einen Code geschrieben welcher sich mit einem kleinen Spiel in der Kommandozeile von Windows beschäftigt. Hierfür werden Sprites erstellt und auch gelöscht wenn sie von einem "Feuerball" welcher von dem "Helden" geschossen wird getroffen werden.
Hierfür habe ich folgenden Code Abschnitt in der update(); Funktion:
for (Iter = npc.begin(); Iter != npc.end(); Iter++) { (*Iter)->idleUpdate(); if ((*Iter)->isAlive() == false) { Sprite *temp = *Iter; Iter--; delete temp; npc.remove(temp); } }Er prüft hierbei immer in der Zeit in der "nichts" passiert, ob der Sprite noch am Leben ist (isAlive()) und falls nicht, löscht er diesen, damit nicht unnötiger Speicher belegt wird.
Es befinden sich 3 Gegner in dem level.
Während der Laufzeit kommt, meistens nach dem ersten Gegner, sobald ein Feuerball auf den 2ten Gegner trifft folgende Fehlermeldung:"list literator not decrementable"
Ich weiß auch schon ungefähr warum dieser Fehler auftrifft, konnte jedoch bisher noch keine funktionierende Umgehung zustande bringen.
Falls noch weitere Code benötigt wird, bitte sagen.
Vielen Dank
-
Das Dekrementieren des
begin()-Iterators führt zu undefiniertem Verhalten. Das Weiteriterieren, nachdem Elemente aus dem Container gelöscht wurden, unter Umständen auch. Was ist das für ein Container, der eineremove()-Methode hat? Oder hast du dich nur verschrieben und meinsterase()?Statt deines Vorgehens solltest du den Rückgabewert von
erase()nutzen, um einen gültigen Iterator zu erhalten. Oder gleich Algorithmen wiestd::remove_if()verwenden - Beschreibung steht auf www.cplusplus.com. Noch einige andere Dinge:Iter++ist langsamer als++Iter, da hierfür eine Kopie erstellt wird.- Boolsche Bedingungen muss man nicht explizit auf
trueoderfalseprüfen, es reicht, wenn duif (Bedingung)oderif (!Bedingung)schreibst. - Willst du wirklich Zeiger im Container speichern und den Speicher selbst verwalten? Da können schneller Fehler (insbesondere Memory Leaks) entstehen, als du vielleicht annimmst. Speichere wenn möglich direkt Objekte statt Zeigern. Eine Alternative wären Boosts Pointer-Container.
-
Habs jetzt etwas anders gelöst:
std::list< Sprite * >::iterator Iter = npc.begin(); std::list< Sprite * >::iterator end = npc.end(); while (Iter != npc.end()) { (*Iter)->idleUpdate(); Sprite *temp = *Iter; if ((*Iter)->isAlive()) { ++Iter; } else { delete (temp); Iter = npc.erase(Iter); } }Glaube auch nicht, dass das die optimalste Lösung ist, aber es funktioniert erstmal. Danke für die Hilfe Nexus