Gå til innhold

iterator blir ugyldige etter kall til erase


Anbefalte innlegg

Hei!

Jeg har jobbet litt med et veldig enkelt spill skrevet i SDL, men får problemer når jeg skal fjerne "asteroidene":

std::vector<Asteroid>::iterator ii;
for(ii = astros.begin(); ii != astros.end(); ii++) {

   if(collision(ship, *ii))
       game_over();

   int itcnt = 0;
   std::vector<SDL_Rect>::iterator jj;
   for(jj = bullets.begin(); jj != bullets.end(); jj++, itcnt++)
       if(collision(*ii, *jj)) {
           astros.erase(ii);
           bullets.erase(jj);
       }
}

Det som skjer er at når jeg kallererase, blir iteratoren jj (og alle andre iteratorer som peker til noe i bullets) ugyldig. Noen som har noen forslag til hvordan jeg kan "restore" verdien til iteratorene? Eller kanskje gjøre det på en helt annen måte?

 

Poenget er at jeg itererer gjennom bullets, og sjekker etter eventuelle kollisjoner. Om det forekommer noen kollisjon, vil jeg slette det ii og jj peker til.

 

Sikkert en veldig enkel løsning på dette, men har liksom sett meg blind på hele shaiten :roll:

Endret av zirener
Lenke til kommentar
Videoannonse
Annonse
Hei!

Jeg har jobbet litt med et veldig enkelt spill skrevet i SDL, men får problemer når jeg skal fjerne "asteroidene":

...

5769689[/snapback]

The erase() function either deletes the element at location loc, or deletes the elements between start and end (including start but not including end). The return value is the element after the last element erased.

 

...

 

Du kan kanskje bruke:

ii = astros.erase(ii);

jj = bullets.erase(jj);

Endret av hishadow
Lenke til kommentar

Får fortsatt SIGSEGV error her. Mulig det da er noe annet som er feil, selv om jeg ikke kan skjønne hva det kan være ettersom ting funker fint når jeg ikke bruker erase. :hmm:

Men, men, får bare fortsette å prøve, intill vidre :)

Endret av zirener
Lenke til kommentar
Får fortsatt SIGSEGV error her. Mulig det da er noe annet som er feil, selv om jeg ikke kan skjønne hva det kan være ettersom ting funker fint når jeg ikke bruker erase. :hmm:

Men, men, får bare fortsette å prøve, intill vidre :)

5769787[/snapback]

En liten feil jeg oppdaget på det jeg postet ... for løkkene inkremeterer ii, jj en gang for mye hvis erase brukes. Hopper over et ledd da.

 

Også, en feil i din kode. Hvis den innerste for loopen sletter ii, vil den fortsette å teste med en slettet ii.

 

std::vector<Asteroid>::iterator ii;

ii = astros.begin()

while(ii != astros.end()) {
  if(collision(ship, *ii))
      game_over();

  bool hasCollision = false;
  int itcnt = 0;
  std::vector<SDL_Rect>::iterator jj;
  jj = bullets.begin();
  while(jj != bullets.end()) {
      if(collision(*ii, *jj)) {
          hasCollision = true;
          jj = bullets.erase(jj);
          continue;
     }
  }

  if(hasCollision) {
     ii = astros.erase(ii);
     continue;
  }

  ii++;
}

Lenke til kommentar

Blir vel kanskje break; i den innerste while-løkka!? og en jj++;

 

Altså:

while(jj != bullets.end()) {
     if(collision(*ii, *jj)) {
         hasCollision = true;
         jj = bullets.erase(jj);
         break;
    }
    jj++;
 }

Endret av ieei
Lenke til kommentar
Blir vel kanskje break; i den innerste while-løkka!? og en jj++;

 

while(jj != bullets.end()) {

      if(collision(*ii, *jj)) {

          hasCollision = true;

          jj = bullets.erase(jj);

          break;

    }

    jj++;

  }

Se den ja :)

Endret av hishadow
Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
×
×
  • Opprett ny...