Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » Löschen via Iterator in einer Schleife?

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
09.06.2006, 21:39 Uhr
FunnyDingo



Hallo zusammen,

ich habe gerade versucht, ein Element aus einem Vector zu entfernen während ich in einer Schleife den Iterartor durchlaufe (gibt es dazu das Verb "iterieren?"). Ich bekomme den Code auch compiliert, aber wenn er dann in den Code abschnitt kommt, stürzt meine Anwendung mit einemr Speicherzugriffsverletzung ab.

C++:
void userdatabase::clean() {
    vector<struct myStruct>::iterator it;
    time_t now;
    time(&now);
    for (it = myStructVector.begin(); it != myStructVector.end(); it++) {
        cout << it->created << ": " << difftime(now, it->created) << endl;
        if (difftime(now, it->created) >= 30) {
            myStructVector.erase(it);
            cout << "Removed..." << endl;
        }
    }
}

Die Ausgabe sieht dann so aus:

Zitat:
21:19:44.938749 Cleaning started
1149880745: 39
Removed...
979724129: 1.70157e+08
Speicherzugriffsfehler

Sinn des ganzen soll halt sein, den Vector zu durchlaufen und alle Elemente die seit mehr als 30 Sekunden bestehen aus dem Vector zu entfernen. Ich nehme mal an das diese kein besonders seltens Vorhaben ist und irgendwie geht das doch bestimmt - aber sorry, ich finde irgendwie keinen Lösungsansatz.

lg,
Funny
--
"Der Computer ist die logische Weiterentwicklung des Menschen: Intelligenz ohne Moral." (John James Osborne)

Meine Website: http://www.funnydingo.de
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
10.06.2006, 02:14 Uhr
Spacelord
Hoffnungsloser Fall


Hi,
du musst deinen iterator mit dem Rückgabewert von erase aktualisieren.Dein iterator ist nach erase ungültig wodurch auch deine for Schleife mit it++ nicht funktionieren wird.
erase liefert dir nen iterator auf das erste Element hinter dem gerade entfernten oder end.
Damit solltest du dir ne while Schleife basteln.

remove_if könnte auch interessant für dich sein.
Kannst du dir ja mal anschauen.

C++:
#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>

using namespace std;

int main()
{
    vector<int> int_vec;
    for(int i=0;i<10;++i)
        int_vec.push_back(i);
    copy(int_vec.begin(),int_vec.end(),ostream_iterator<int>(cout," "));
    cout<<endl;

    vector<int>::iterator it = int_vec.begin();
    while(it != int_vec.end())
    {
        it = int_vec.erase(it);
        copy(int_vec.begin(),int_vec.end(),ostream_iterator<int>(cout," "));
        cout<<endl;
    };
    cout<<endl;

    for(int i=0;i<10;++i)
        int_vec.push_back(i);
    //ungerade Elemente "entfernen"
    it = remove_if(int_vec.begin(),int_vec.end(),bind2nd(modulus<int>(),2));
    int_vec.erase(it,int_vec.end());

    copy(int_vec.begin(),int_vec.end(),ostream_iterator<int>(cout," "));
    cout<<endl;

    return 0;
}



Gruss Spacelord
--
.....Ich mach jetzt nämlich mein Jodeldiplom.Dann hab ich endlich was Eigenes.

Dieser Post wurde am 10.06.2006 um 02:28 Uhr von Spacelord editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
10.06.2006, 09:01 Uhr
Spacelord
Hoffnungsloser Fall


Moin,
nur um es noch nachzuschieben.....die Performance von der erase Geschichte ist ziemlich übel.
Sofern die Objekte zum Zeitpunkt ihrer Erzeugung immer ans Ende angehangen werden ergibt sich ja zwangsläufig dass das erste Element auch das älteste ist.Dann musst du den Container nur solange durchlaufen bis das erste Element auftaucht dass noch nicht alt genug ist.
Dafür müsstest du dir aber nen geeigneten Container suchen der Einfügen und Entfernen am Anfang und Ende in konstanter Zeit ermöglicht und nicht erst grossartig Elemente verschieben und kopieren muss.

Gruss Spacelord
--
.....Ich mach jetzt nämlich mein Jodeldiplom.Dann hab ich endlich was Eigenes.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
10.06.2006, 10:58 Uhr
FunnyDingo



Erstmal danke für den Tipp. Hab danach direkt mal nen Blick in die CPP-Reference zum erase geworfen und da ist es mir doch glatt ins Auge gesprungen *g*. Manchmal ist man einfach Blind.

Dein zweiter Kommentar ist ein guter Tipp, werde ich mir mal genauer ansehen.
--
"Der Computer ist die logische Weiterentwicklung des Menschen: Intelligenz ohne Moral." (John James Osborne)

Meine Website: http://www.funnydingo.de
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
10.06.2006, 11:07 Uhr
FunnyDingo



Ich musste aus der for-Schleife noch eine While-Schleife machen, sonst hat es durch das inkrementieren des Iterators noch einen Fehlergegeben. Sieht nun so aus:

C++:
void userdatabase::clean() {
    vector<struct myStruct>::iterator it = myStructVector.begin();
    time_t now;
    time(&now);
    while(it != myStructVector.end()) {
        cout << it->created << ": " << difftime(now, it->created) << endl;
        if (difftime(now, it->created) >= 30) {
            it = myStructVector.erase(it);
            cout << "Removed..." << endl;
        } else {
            it++;
        }
    }
}


Ist zwar im Bezug auf die Performance noch nicht ideal, aber so kann der Vector schon mal aufgeräumt werden, was für die ersten Tests sehr wichtig ist.

lg,
Funny
--
"Der Computer ist die logische Weiterentwicklung des Menschen: Intelligenz ohne Moral." (John James Osborne)

Meine Website: http://www.funnydingo.de
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
11.06.2006, 12:21 Uhr
(un)wissender
Niveauwart


Nimm doch sonst std::list
--
Wer früher stirbt ist länger tot.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: