2017-01-27 4 views
0

Ich habe einen Vektor von Klassenobjekten (Aufzählungszeichen) und es funktioniert zum größten Teil. Aber sobald ich versuche, die Kugeln zu löschen, springt es zurück und verursacht dann einen Haltepunkt. "basic game.exe hat einen Haltepunkt ausgelöst." Ich habe versucht, rückwärts und vorwärts zu iterieren, aber es bleibt immer hängen.Löschen von Daten im Vektor über Schleife, die Haltepunkte verursacht

Ich benutze SFML, und die Objekte sind Rechteck mit Positionen, Rotationen und Größen.

for (it = bullets.end(); it != bullets.begin(); it--) 
    { 
     it->draw(game); 
     it->move(); 
     if (it->bullet.getPosition().x > 800) 
     { 
      bullets.erase(it); 
     } 
    } 

Ich bin ein Noob bei der Codierung, wenn Sie also andere Infomation brauchen, versuchen Sie es und stellen Sie es zur Verfügung.

+3

ein Element aus einem 'std :: VECTOR' Löschen wird ungültig alle seine Iteratoren (in diesem Fall' Es ') , undefiniertes Verhalten aufrufen (weil Sie versuchen, 'it-1' im nächsten Schleifenzyklus zu verwenden,' it-> draw (Spiel); // Zugriff auf ungültigen Iterator '). – George

+0

Was aber gültig ist, ist bullets.erase (it--); aber dann musst du deine for-Schleife noch einmal überdenken – UKMonkey

+1

Sogar zuerst 'it-> zeichnen (Spiel);' ist UB (wie 'es' ist 'end()'). – Jarod42

Antwort

4

Wenn Sie erase() für einen Vektor aufrufen, werden die Iteratoren ungültig. betrachten Stattdessen versuchen diese:

for (auto it = bullets.begin(); it != bullets.end();) 
{ 
    it->draw(game); 
    it->move(); 
    if (it->bullet.getPosition().x > 800) 
    { 
     it = bullets.erase(it); 
    } 
    else 
    { 
     it++; 
    } 
    } 
+0

Ich habe meinen Code geändert und es hat funktioniert. Danke, aber kannst du erklären, warum das funktioniert und meins nicht? – Mitchell

+0

@Mitchell Nach dem Aufruf von Erase wird der Iterator ungültig. Erase() gibt einen Iterator an das Element zurück, das dem gelöschten Element folgt, und validiert daher den Iterator erneut, was im Code über –

+0

@Kevin passiert. Ich habe falsch gelesen und verpasst, dass die Rückkehr von 'radier()' verwendet wird setze 'es' zurück. Downvode => upvote. – YSC

3

Sie beheben können Ihre Schleife mit

for (auto& bullet : bullets) { 
    bullet.draw(game); 
    bullet.move(); 
} 
bullets.erase(std::remove_if(bullets.begin(), bullets.end(), 
          [](const auto& bullet) { 
           return bullet.getPosition().x > 800; 
          }), 
       bullets.end()); 
+0

Ich denke, Ihr Löschen ist ein wenig falsch (neben "bullet :: Erase" anstelle von "bullets.erase"). Sie müssen auch den Ende-Iterator angeben. – Kevin

+0

@Kevin: In der Tat, Tippfehler behoben. – Jarod42

Verwandte Themen