Etwas ordentlich aus einem vector löschen?



  • Hi,

    wie kann ich etwas ordentlich aus einem vector löschen? jedesmal wenn ich was rauslösche und ich bei 0 angekommen bin schmiert das programm ab 😞

    Kann mir jemand ein beispiel zeigen wie ich das ordentlich mache?



  • ''' schrieb:

    edesmal wenn ich was rauslösche und ich bei 0 angekommen bin schmiert das programm ab 😞

    Das ist eine schlechte Fehlerbeschreibung.

    Kann mir jemand ein beispiel zeigen wie ich das ordentlich mache?

    Zeig du uns doch deinen Code, dann sagen wir dir, was daran falsch ist.



  • // Ball updaten
        for (unsigned int i=0; i<vec_ball_.size(); ++i)
            vec_ball_[i].update (delta);
    
        // testen ob ball verloren, wenn ja löschen
        for (vec_ball_it_=vec_ball_.begin(); vec_ball_it_!=vec_ball_.end(); ++vec_ball_it_)
        {
            if (vec_ball_it_->getY() > 480)
                vec_ball_it_ = vec_ball_.erase (vec_ball_it_);
        }
    
        // wenn kein ball mehr enthalten ist einen neuen erstellen
        if (vec_ball_.size() < 1)
        {
            vec_ball_.push_back( ball (20, 20, 7, 7, true, 275, 275, true, this));
            ::PlaySound ("data/sfx/lose.wav", NULL, SND_ASYNC);
        }
    

    Das passiert immer nur wenn ich den letzten ball lösche 😞



  • ''' schrieb:

    // testen ob ball verloren, wenn ja löschen
        for (vec_ball_it_=vec_ball_.begin(); vec_ball_it_!=vec_ball_.end(); ++vec_ball_it_)
        {
            if (vec_ball_it_->getY() > 480)
                vec_ball_it_ = vec_ball_.erase (vec_ball_it_);
        }
    

    Das passiert immer nur wenn ich den letzten ball lösche 😞

    Das sollte auch noch andere Fehler verursachen. Das Problem ist, dass erase dir den nächsten Iterator zurückgibt. Der wird aber vor dem nächsten Schleifendurchlauf nochmal inkrementiert. Du überspringst also immer einen Eintrag. Und wenn du den letzten Eintrag löschst, inkrementierst du über den end-Iterator hinweg, und es knallt.

    Du könntest das Inkrement aus dem Kopf der Schleife entfernen und statt dessen in der Schleife den iterator erhöhen, aber nur, wenn du nicht erase aufrufst.



  • for (vec_ball_it_=vec_ball_.begin(); vec_ball_it_!=vec_ball_.end(); )
    {
        if (vec_ball_it_->getY() > 480)
            vec_ball_it_ = vec_ball_.erase (vec_ball_it_);
        else
            ++vec_ball_it_;
    }
    


  • in diesemfall wurde dann also bei der konstruktion geschlampt von seiten der STL Coder? 😮



  • ++++++++++++++++++++++ schrieb:

    in diesemfall wurde dann also bei der konstruktion geschlampt von seiten der STL Coder? 😮

    Nein. Wie kommst du darauf?



  • weil man das nicht normal mit einer forschleife machen kann und im header der forschleife inkremetieren kann 😮



  • ++++++++++++++++++++++ schrieb:

    weil man das nicht normal mit einer forschleife machen kann und im header der forschleife inkremetieren kann 😮

    Wenn du das falsche Werkzeug (oder das richtige Werkzeug falsch) benutzt, ist das deine eigene Schuld. Sowohl for als auch vector::erase sind standardisiert. Wenn du da mit deinen "normalen" Implementierungs-Mittelchen nicht weiterkommst, liegt es an dir.



  • bei for wird der 3. parameter zur inkrementierung benutzt also wirds richtig benutzt



  • ++++++++++++++++++++++ schrieb:

    bei for wird der 3. parameter zur inkrementierung benutzt

    So pauschal: Nein.

    also wirds richtig benutzt

    Tipp: Scheuklappen abnehmen 😉



  • geschlampt haben die nicht. dein problem, ein element aus einem vektor zu löschen, ist nur komplizierter als es auf den ersten blick aussieht.

    MFK hat das problem bereits richtig beschrieben. allerdings ist das für einen anfänger nicht leicht zu verstehen.

    hier mal mein code-vorschlag zu lösung des problems:

    // testen ob ball verloren, wenn ja löschen 
    vec_ball_it_=vec_ball_.begin();
    while(vec_ball_it_!=vec_ball_.end())
      if(vec_ball_it_->getY()>480) 
        vec_ball_it_=vec_ball_.erase (vec_ball_it_); 
      else
        ++vec_ball_it;
    

    der knackpunkt ist halt, daß der von erase() gelieferte iterator anschließend nicht auch noch inkrementiert werden darf. der zeigt nämlich bereits auf das nächste element! geht ja auch nicht anders, denn das aktuelle element ist ja nach aufruf von erase() nicht mehr vorhanden.



  • Hast recht, ich kapiere nicht wieso dort nicht nachgedacht wurde und das man nicht so schön mit einer for löschen kann 😞 Das find ich scheiße das man dafür noch ein else hinzufügen muss und den 3. parameter bei for leer lassen muss 😞



  • tschuldigung! hab nicht gemerkt, daß jemand die lösung bereits geposted hat 🤡


Anmelden zum Antworten