der ast auf dem man sitzt? iterator und list.erase()
-
ich habe eine doppeltverlinkte liste mit eigenen objekten.
std::list<MyObject> listnun will ich mit
std::list<MyObject>::iterator itüber diese liste iterieren, bei jedem element checken ob es gekillt werden darf, wenn ja killen mit
list.erase(it)In allen tutorials und codebeispielen die ich gefunden habe wurde das auch so geschrieben wie wir es haben. unsere vermutung ist jedoch, dass wir auf einem ast sitzen den wir absegen wollen.
konsequenz:SpeicherzugriffsfehlerIrgendjemand eine ahnung?
danke
-
IIRC invalidiert erase alle Iteratoren.
-
ich versteh nicht was du meinst?
-
Du kannst es so sehen dass du dir mit erase den Ast absägst auf dem du sitzt.
Beim einfügen und löschen von elementen eines containers werden manche iteratoren ungültig. Welche ist abhängig vom container-typ.
Kurt
-
it = list.erase(it);
-
ich würde es nicht empfehlen - du benötigst einen gültigen Iterator, um weitermachen zu können und der gerade gelöscht ist nicht mehr gültig.
Also Fazit: kopieren, weiterzählen, und anschließend über die Kopie das Element löschen:
typedef list<MyClass>::iterator listit; for(listit it=liste.begin();it!=liste.end();) { listit kopie=it++;//post-Inkrement -> kopie erhält Wert vor Inkrement if(loeschbar(*kopie) liste.erase(kopie); }Edit: Btw, bei std::list wird nur der gelöschte Iterator ungültig

-
typedef list<MyClass>::iterator listit; for (listit it=liste.begin();it!=liste.end();) { if (loeschbar(*it)) { it = liste.erase(it); } else { ++it; } }
-
einen haufen fehler hats verursacht. gehen erstmal essen.
-
Warum verwendest du nicht gleich list::remove_if()?
bool checkFunc(int const& val) { if(/* bedingung */) { return true; } return false; } liste.remove_if(&checkFunc);Gruß
-
remove_if() ist hier gut geeignet, aber bedenke, dass du nachher noch erase aufrufen musst. Also konzeptionell:
erase(remove_if())Ein kleiner Trick, der mir erstmals vor kurzem im Meyers (STL) aufgefallen ist:
l.erase(it++)Ist kurz zu schreiben und korrekt (it steht nach dem Löschen am nächsten Element).
-
finix schrieb:
typedef list<MyClass>::iterator listit; for (listit it=liste.begin();it!=liste.end();)- muss in der genericDef nich ein * nach dem objektnamen gesetzt werden?
- kann das sein dass in der forschleife das inkrement vergessen wurde?

-
benshman schrieb:
finix schrieb:
typedef list<MyClass>::iterator listit; for (listit it=liste.begin();it!=liste.end();)- muss in der genericDef nich ein * nach dem objektnamen gesetzt werden?
Wie bitte?
- kann das sein dass in der forschleife das inkrement vergessen wurde?
Nicht vergessen, absichtlich ausgelassen (weil der Iterator bereits innerhalb der Schleife weitergezählt wird).
-
typedef list<MyClass*>::iterator listit;qausi so
-
Das kommt ganz darauf an, wie deine Liste definiert ist - du benötigst den iterator des verwendeten Listentyps (und zu list<MyObject> aus deinem Eröffnungsbeitrag gehört list<MyObject>::iterator (ohne *)).
-
super.
danke.klappt alles super!

danke nochmal!