Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

[sfml] usuwanie obietku z vectora [rozwiązany]

Ostatnio zmodyfikowano 2013-01-14 17:18
Autor Wiadomość
bari
Temat założony przez niniejszego użytkownika
[sfml] usuwanie obietku z vectora [rozwiązany]
» 2013-01-14 15:05:11
Witam. Mam problem, z którym borykam się od wczoraj. W SFML w pętli while(Okno.isOpen()) rysuje obiekty, które chciałbym skasować przy pewnych założeniach.

Mam obiekt "aktualnyLevel" klasy Plansza. Zawiera on w sobie vector elementów typu Pocisk. Chciałbym, by elementy te zostały skasowane z pamięci kiedy wylecą poza obramowanie ekranu:
C/C++
for( vector < Pocisk *>::iterator pocisk = aktualnyLevel->getGracz()->rakiety.begin(); pocisk != aktualnyLevel->getGracz()->rakiety.end(); )
{
    int x =( * pocisk )->getX();
    int y =( * pocisk )->getY();
   
    if(( x < 0 || x > desktop.width ) ||( y < 0 || y > desktop.height ) )
    {
        delete * pocisk;
        aktualnyLevel->getGracz()->rakiety.erase( pocisk );
    }
    else
    {
        ( * pocisk )->ruch( & event );
        Okno.draw(( * pocisk )->getSprite() );
    }
    pocisk++;
}

problem w tym, że aplikacja się wysypuje z komunikatem "vector iterators incompatible". Nie rozumiem, gdzie może wystąpić niekompatybilność, skoro cały czas operuje na tym samym iteratorze.

Dodam, że jeśli okomentuję zawartość if'a, wówczas wszystko działa jak należy, z tym, że obiekty pozostają w pamięci, co z oczywistych względów jest nie do zaakceptowania.

Pozdrawiam i z góry dziękuję za pomoc
P-73930
DejaVu
» 2013-01-14 16:34:21
Nie można kontynuować iteracji w std::vector po usunięciu elementu. Używaj albo indeksów, albo rozpoczynaj iterację od początku (ale to raczej chybiony pomysł).
P-73939
ison
» 2013-01-14 16:38:10
Nie można kontynuować iteracji w std::vector po usunięciu elementu
Można, erase zwraca iterator kolejnego elementu po usunięciu.

@bari, pod pocisk podstaw to co zwróci erase, a pocisk++; wrzuć do else.
P-73940
DejaVu
» 2013-01-14 16:47:16
Hę? std::vector? Przecież może dojść do realokacji całej tablicy i wszystkie iteratory szlag trafi...

/edit:
Racja :P Myślałem, że erase w std::vector zwraca void-a :P A tu niespodzianka :)
P-73942
bari
Temat założony przez niniejszego użytkownika
» 2013-01-14 17:18:48
rozwiązane

pocisk = aktualnyLevel->getGracz()->rakiety.erase(pocisk);
zamiast aktualnyLevel->getGracz()->rakiety.erase(pocisk);

tak oczywisty błąd, a tyle szukania, no ale tak bywa, że większość czasu w debuggerze spędza się w poszukiwaniu średnika ;)

ps. ison widzę, że też to zauważył, dzięki ;)
P-73947
« 1 »
  Strona 1 z 1