std::list::iterator Gültigkeitsfrage.
-
Ich hab in einem meiner Programme gerade einen Bug und hab ihn auf ein
eine etwas unsaubere Stelle im Code zurückgeführt.1 Ich habe eine std::list, aus dieser Liste entferne ich ein Objekt
behalte jedoch den Iterator der auf das Objekt verwies!
old = *old_it;
old_it = path.erase(old_it);2 Danach füge ich es wieder in die Liste ein.
old_it = path.insert(old_it,old);
Bis hierhin sollte eigentlich noch alles stimmen3 Jetzt lösche ich ein anderes Objekt aus der Liste (z.B. das direkt dahinter)
act = *it;
it = path.erase(it);4 Nun lösche ich das Alte wieder

old_it = path.erase(old_it);5 Und füge das andere Objekt wieder ein
it = path.insert(it,act);Ich habe die Vermutung das bei diesem Vorgang einer der beiden Iteratoren ungültig wird.
D.h. wenn ich den Alten wieder lösche, der Iterator des Anderen Objektes ungültig wird.Der Bug macht sich übrigens in einer Endlosschleife bemerkbar. Der Schleifenkopf ist dabei:
for(it=path.begin(); it != path.end(); it++)Ich weis das Alles ist etwas komplex, aber vllt. macht sich ja jemand
die Mühe sich da kurz reinzudenken. Mir wäre auch schon geholfen wenn jemand
sagt, ja der Iterator wird definitv ungültig, dann kann ich den Ganzen
Ansatz gleich verwerfen.
-
Hmm erase gibt dir den Iterator für das nächste Item in der Liste zurück.
-
poste doch mal deinen quelltext, dann kann man dir vielleicht erzählen was sich genau abspielt.
-
*glaskugel herauskram*
Storm.Xapek.de schrieb:
1 Ich habe eine std::list, aus dieser Liste entferne ich ein Objekt
behalte jedoch den Iterator der auf das Objekt verwies!
old = *old_it;
old_it = path.erase(old_it);2 Danach füge ich es wieder in die Liste ein.
old_it = path.insert(old_it,old);
Bis hierhin sollte eigentlich noch alles stimmennö, du behältst nicht den iterator, auf den das element verwies. du behältst den wert ('old') und old_it zeigt nach dem erase des elements, auf das es zeigte, auf das element, das danach kommt.
3 Jetzt lösche ich ein anderes Objekt aus der Liste (z.B. das direkt dahinter)
act = *it;
it = path.erase(it);aha, das ist das problem. das element, das direkt hinter dem gerade gelöschten kommt, ist das element, auf das old_it jetzt zeigt. erase invalidiert bei einer liste alle iteratoren auf das objekt, das gelöscht wird, damit zeigt old_it ab jetzt ins nirvana.
4 Nun lösche ich das Alte wieder

old_it = path.erase(old_it);und einen iterator, der ungültig ist, zu verwenden, fliegt dir um die ohren.
5 Und füge das andere Objekt wieder ein
it = path.insert(it,act);soweit kommt's wahrscheinlich gar nicht.
std::list::erase invalidiert wie gesagt nur die iteratoren, die auf das gelöschte element zeigen. es lässt alle anderen unberührt.
-
Danke fürs durchlesen und für die Antworten.
Ich habe den Ansatz inzwischen doch ganz verworfen...