[STL-Container] Gleichzeitig einfügen und auslesen
-
Hallo,
folgendes vereinfachtes Problem habe ich:
#include <list> int main() { //Die Liste list<int> meineliste; meineliste.push_back(1); meineliste.push_back(2); meineliste.push_back(3); //Ueber die ganze liste laufen for(list<int>::iterator i= meineliste.begin(); i != meineliste.end(); ++i) { if ( (*i) == 2 ) { //und waehrendessen was unerwartet mit anderen Iterator einfuegen list<int>::iterator i_insert= meineliste.begin(); ++i_insert; ++i_insert; //etwas rumpositionieren meineliste.insert(i_insert, 99); } //gleichzeitig die Liste auslesen cout << (*i) << endl; } return 0; }Dazu habe ich folgende Fragen:
1. Wird der Iterator i nicht illegal, wenn sich untendrunter die Liste mengenmaessig bewegt?
2. Wie koennte man das Problem loesen, gibt es vielleicht spezielle Iteratoren, die sowas aushalten?
Danke
-
@1: Bei vector'en vielleicht (wenn der insert() die reservierte Größe verändert), bei list'en definitiv nicht - der list::iterator bleibt gültig, solange du das Element selber nicht löschst.
@2: Für Listen ist es wie gesagt nicht nötig, für vector könntest du einen Wrapper-Iterator schreiben, der sich nicht die physikalische Adresse merkt, sondern den Index.
-
Danke für die schnelle Hilfe.
Ein delete() muss auf die Elemente auch zur Laufzeit gemacht werden, es ist aber fast egal, welchen Container ich verwende.
Bei einer list<> hangelt sich der Iterator doch via verketteten Listen vor:
Wenn der Iterator den Pointer des aktuellen Elementes verwendet und nicht intern die Pointer hält, geht das fast immer gut, ausser das aktuelle Element wird gelöscht.
Das kann ich aber nicht ausschliessen.Gibt's vielleicht ein Container, der sowas robuster mitmacht?
Gruss
Markus
-
Bei einem erase()-Aufruf wird das entsprechende Element gelöscht - Iteratoren, die genau auf dieses Element gezeigt haben, sind damit in jedem Fall ungültig (und da ist es egal, welchen Container du verwendest - was gelöscht wird, ist weg).
Bei Iteratoren, die nicht auf das gelöschte Element zeigen, sieht die Situation deutlich besser aus: Bei vectoren und deques werden die Elemente hinter (bzw. vor) dem Element umkopiert, d.h. die Iteratoren zeigen vermutlich noch in den Container, aber nicht mehr auf das richtige Element; bei listen und sequentiellen Containern werden lediglich ein paar Zeiger verbogen - davon bekommen die iteratoren überhaupt nichts mit.
-
Danke für die genaue Antwort.
Bekommen die Iteratoren mit, wenn sie ungültig sind?
Wenn man das bei denen abfragen koennte, koennte ich mein Problem so loesen.
Zur Not könnte ich das aber auch selbst implementieren.
-
markus.r schrieb:
Bekommen die Iteratoren mit, wenn sie ungültig sind?
Leider nein (genausowenig wie ein Pointer mitbekommt, wenn jemand anderes ihm die Daten delete'd). Die einzige Lösung, die mir spontan einfallen würde, wäre vor dem Löschen alle bekannten Iteratoren in der Liste abzufragen, ob sie auf das zu löschende Element zeigen (oder du baust dir eine eigene Liste mit Referenzzählung, die solch Situationen abfängt).
-
sowohl insert (iterator, T) als auch erase liefern einen iterator zurueck.
das sollte in der praxis dazu beitragen koennen einige probleme zu umgehen.