Objekt aus Liste löschen (List iterator not incrementable)



  • Hallo Forum,

    Ich habe eine Reihe von Objekten in eine Liste geladen:

    srand(GetTickCount());
    while(k < 5) {					
     Sprite *osMonster = new Sprite;					
     osMonster->createSpriteFromFile(Direct3D.GetDevice(), "monster.bmp");		   
     osMonster->setSpritePosition(rand()%800, rand()%600);
     osMonster_List.push_back(osMonster);
     k++;
    }
    

    Nun möchte ich, wenn ich mit dem Mauszeiger über so ein Objekt (also in dem Fall ein Monster-Sprite) fahre und draufklicke, dieses Objekt aus der Liste löschen.
    Dafür habe ich mir folgenden Code überlegt, der jedoch nicht richtig funktioniert:

    case WM_LBUTTONDOWN:
    [...]
    POINT pt; 
    GetCursorPos(&pt);
    for(it=osMonster_List.begin();it!=osMonster_List.end();it++) {
    	if( (pt.x > (*it)->getSpritePosition().x) && (pt.x < (*it)->getSpritePosition().x + SpriteWidth) 
    && (pt.y > (*it)->getSpritePosition().y) && (pt.y < (*it)->getSpritePosition().y + SpriteHeight) ) {
       delete *it;	
       it = osMonster_List.erase(it);				   
       }
    }
    

    Das scheint nur manchma spontan zu funktionieren. Ich kann 2-3 Sprites anklicken , aber dann stürzt mir das Programm mit der Meldung: "List iterator not incrementable" ab :(!

    Ich nutze Microsoft Visual Studio 2005 und DirectX9.

    Bin für jede Hilfe äußerst dankbar!

    Tschau
    Sandro



  • skummy schrieb:

    .. Das scheint nur manchma spontan zu funktionieren. Ich kann 2-3 Sprites anklicken , aber dann stürzt mir das Programm mit der Meldung: "List iterator not incrementable" ab :(!

    Du darfst den Iterator dann nicht mehr inkrementieren, wenn Du ihn bereits als return-Code von erase bekommen hast. Denn dieser kann bereits der Ende-Iterator sein, beim Löschen des letzten Elements in der Liste. Also besser:

    case WM_LBUTTONDOWN:
        // [...]
        POINT pt;
        GetCursorPos(&pt);
        for(it=osMonster_List.begin();it!=osMonster_List.end();) {
            if( /* Monster mit Maus getroffen */ ) {
                delete *it;   
                it = osMonster_List.erase(it); 
                // it zeigt jetzt bereits auf das nächste Element hinter dem gelöschten                  
            }
            else
                ++it;   // nur inkrementieren, falls es nicht gelöscht wurde
        }
    

    Gruß
    Werner



  • Geht auch nicht.

    Ich habe aber inzwischen herausgefunden, dass nach dem erase ein "return 0;" folgen muss.
    Warum das aber so sein muss, entzieht sich meines Wissens...



  • skummy schrieb:

    Geht auch nicht.

    doch doch! Hast Du auch nicht vergessen das it++ in der for-Schleife zu löschen?



  • Ohhh...du versteckst dich doch in meinem Zimmer und kannst auf meinen Quelltext schauen ;)!

    Spaß bei Seite...du hattest Recht. Ich hab vergessen das it++ in der for-Schleife zu entfernen. Jetzt funktioniert alles bestens :)! Auch ohne die "return 0;"-Zeile

    Vielen vielen Dank an dich!!


Anmelden zum Antworten