List iterator not incrementable



  • Habe eine STL list, die alle 10 Sekunden lang mit einer Instanz durch "pushback" einen neuen Eintrag erhält. Überschreitet ein Objekt dieser Liste eine bestimmte Position in meinem SFML Window, dann wird es aus der Liste entfernt (die Liste enthält pointer zu den Instanzen)

    for (auto it = mList.begin(); it != mList.end(); ++it) {
    		if ((*it)->getSprite().getPosition().y > 400) {
    			delete (*it);
    			(*it) = nullptr;
    
    			mList.erase(it);
    			//std::cout << "Destroyed" << std::endl;
    		}
    

    Jetzt habe ich das Problem, dass im Falle eines einzigen Objektes, was dann entfernt wird, mein Programm crasht, mit dem Hinweis "List iterator not incrementable" und ich aber nicht weiss weshalb das so ist. Das Programm dürfte doch gar nicht über die condition in der for-loop hinauskommen für den Fall, dass ie Liste leer ist, wieso beschwert er sich also, dass er ++it nicht kann?



  • Erase gibt einen neuen Iterator zurück, der alte wird ungültig und darf nicht mehr benutzt werden.

    Aber warum list? Und warum delete? Und warum nullptr zuweisen, wenn der Eintrag eh entfernt wird?



  • Bei verändern eines std::vector werden alle auf dessen elemente zeigende iteratoren ungültig. erase gibt dir aber einfach einen neuen iterator auf das dahinter befindliche element zurück.
    Ansonsten solltest du dir mal smartpointer und die bereichsbasierende for-schleife anschauen.



  • Danke schon mal für eure Antworten. Das ganze programmiere ich einem Tutorial nach, danach werde ich meine Verbesserungen einfließen lassen ; ) Die Smartpointer Sache war ein EIntrag auf meiner Liste an Modifikastionen, aber ich würde gerne dennoch verstehen, wie andere Leute an Dinge herangehen. Ok also modifications invalidate iterators.

    Der end-iterator wird eh in jeder iteration neu geholt und erase gibt mir den iterator past the deleted element, bzw. one past the end wieder, wenn die liste leer ist.

    Wenn ich

    it = mList.erase(it);
    

    verwende, crasht das programm aber genauso.

    Die range-based for loop kenne ich, aber die kann ich doch nicht einsetzen, wenn ich die Größe des Containers verändere

    List kann doch Elemente aus aus seiner Mitte mit konstanter Komplexität entfernen im Vergleich zu vector oder? Deshalb List statt vector. nullptr zuweisung habe ich mich auch gefragt: Dangling pointer Gefahr besteht hier ja wohl nicht, wenn der pointer eh im direkt folgenden chritt rausgeschmissen wird



  • jemand eine Idee, was falsch ist?



  • Mach eine while Schleife draus.



  • hatte ich auch überlegt, aber kannst du mir sagen, was hier nicht stimmt, bzw was ne while verbessern würde?



  • Sewing schrieb:

    jemand eine Idee, was falsch ist?

    Du machst wahrscheinlich das it=l.erase(it) und das ++it im Schleifenkopf.



  • ja genau, also inkrementieren nur für den Fall, dass erase nicht aufgerufen wurde?

    Habe versucht das mit while zu machen

    auto iter = mList.begin(); changing vi
    		while (iter != mList.end()) {
    			if ((*iter)->getSprite().getPosition().y > 400 ) {
    				delete (*iter);
    				iter = mList.erase(iter);
    
    			} 
    else
    iter++;
    		}
    

    das läuft 🙂



  • Sewing schrieb:

    ja genau, also inkrementieren nur für den Fall, dass erase nicht aufgerufen wurde?

    Klingt knorke.



  • Danke Furble für deine Hilfe!

    Diese Tutorials sind teilweise wirklich fehlerbehaftet


Log in to reply