Debug Assertion: Vector iterators incompatible.
-
Hallo!
vector <int> vi; vi.push_back(0); vector <int>::iterator it = vi.begin(); int num = *it; it = vi.erase(it); if ( it == vi.end() ) cout << "This is THE END." << endl; // OK vi.push_back(num); if ( it != vi.end() ) // Debug Assertion: Vector iterators incompatible. cout << "This is not THE END." << endl;
Ich bekomme bei der Ausführung des Codes die Meldung:
Debug Assertion: Vector iterators incompatible.
Warum eigentlich und wie geht es richtig?
Meine Vermutung ist: nach Ausführung vonvi.push_back(num);
wird der angeforderte Iterator ungültig.
-
vectorincompatibility schrieb:
Meine Vermutung ist: nach Ausführung von
vi.push_back(num);
wird der angeforderte Iterator ungültig.
Das ist korrekt. Jegliche Veränderung an eine
std::vector
Container führt zur Invalidierung aller Iteratoren auf diesen Container.Kannst du auch sehr schön hier nachlesen:
http://magazin.c-plusplus.net/artikel/Aufbau%20der%20STL%20-%20Teil%201%3A%20ContainerWie man es richtig macht? Nun, durch ein
push_back
kannit
nicht plötzlich auf das Ende verweisen, daher ist diese Kontrolle unnötig.Grüssli
-
Stimmt, in diesem Fall gibts kein Ende, aber ich habe das Problem 'umzingelt' und ein Minimalbeispiel gepostet, wobei es auf folgendes hinausläuft:
Ich möchte nen Vector von Anfang bis Ende durchlaufen und
an beliebiger Stelle Elemente mit erase entnehmen und je nach Bedingung diese Elemente entweder in den Vector mit push_back nach hinten zurückschieben(Position ändern), oder gelöscht lassen.
(In meinem post habe ich das 'gelöscht lassen' weggelassen.)
Nach push_back oder erase soll mit dem nächsten Element weiter gemacht werden. Ist der Iterator am Ende, soll wieder am Anfang weiter gemacht werden, bis der Vector leer ist.Könntest du mir bitte einen Tipp geben, wie man das machen kann?
-
Du brauchst einfach nur ne deque.
deque<Job> todo; while(!todo.empty()){ Job& j=todo.pop_front(); j.run(); if(...) todo.push_back(j); todo.pop_front(); }
(eigentlich riecht die aufgabe nach einem intrisiver nichtleeren doppelt verketteter ring, aber deque ist gut genug)
-
Da kannst du dir ja eine schöne Endlosschleife bauen
Aber warum schiebst du die Elemente nicht anstatt an das Ende in einen neuen Vector? Und wenn der Ursprungsvector leer ist einfach per swap die Elemente umfüllen?
-
Also das klingt ganz klar nach einem Fall für std::list. Da hat man dann auch nicht das Problem, dass die Iteratoren ungültig werden.
-
Wollte mir grade was zurechtbauen:
// Pseudocode vector v, i=0, size = v.size(), L: solange size != 0: - elem e = erase v.at(i) - wenn vector nicht leer: // Lücke auffüllen für alle j = i && j < v.size() -1: v[j] = v[j+1] - v.push_back(e) oder nicht - wenn i == size size = v.size() i = 0 goto L
Aber jetzt habe ich ja viele Tipps bekommen, denen ich nachgehen werde.
Danke erstmal!