Segmentation Fault mit vector



  • Hallo,

    bin verzweifelt auf der Suche nach einem Bug, der bei mir einen segmentation fault auslöst, aber irgendwie steh ich auf dem Schlauch.

    Ich hab jetzt mal mein Problem darauf reduziert, einen vector mit 4 elementen zu füllen, und anschließend alle elemente zu löschen (später will ich ein ganz bestimmtes element löschen).

    NodeID nid1 = NodeID(string("192.168.1.1"),string("1234"));
    	NodeID nid2 = NodeID(string("192.168.1.2"),string("765"));
    	NodeID nid3 = NodeID(string("192.168.1.3"),string("594"));
    	NodeID nid4 = NodeID(string("192.168.1.4"),string("433"));
    
    	printf("Nodes created\n");
    	vector<Neighbour> list = vector<Neighbour>();
    	list.push_back(nid1);
    	list.push_back(nid2);
    	list.push_back(nid3);
    	list.push_back(nid4);
    
    	vector<Neighbour>::iterator theIterator;
    
    	theIterator = list.begin();
    	while(theIterator != list.end()){
    printf("in list, deleting now\n");
    		theIterator = list.erase(theIterator);
    		theIterator++;
    	}
    	printf("list finished\n");
    

    Als Ausgabe bekomme ich :

    Nodes created
    Neighbour::Neighbour(const NodeID& t_nodeid): Entry
    Neighbour::Neighbour(const NodeID& t_nodeid): Exit
    Neighbour::Neighbour(const Neighbour& neighbour) 192.168.1.1:1234
    Neighbour::~Neighbour(): Entry: 192.168.1.1:1234
    Neighbour::Neighbour(const NodeID& t_nodeid): Entry
    Neighbour::Neighbour(const NodeID& t_nodeid): Exit
    Neighbour::Neighbour(const Neighbour& neighbour) 192.168.1.1:1234
    Neighbour::Neighbour(const Neighbour& neighbour) 192.168.1.2:765
    Neighbour::~Neighbour(): Entry: 192.168.1.1:1234
    Neighbour::~Neighbour(): Entry: 192.168.1.2:765
    Neighbour::Neighbour(const NodeID& t_nodeid): Entry
    Neighbour::Neighbour(const NodeID& t_nodeid): Exit
    Neighbour::Neighbour(const Neighbour& neighbour) 192.168.1.1:1234
    Neighbour::Neighbour(const Neighbour& neighbour) 192.168.1.2:765
    Neighbour::Neighbour(const Neighbour& neighbour) 192.168.1.3:594
    Neighbour::~Neighbour(): Entry: 192.168.1.1:1234
    Neighbour::~Neighbour(): Entry: 192.168.1.2:765
    Neighbour::~Neighbour(): Entry: 192.168.1.3:594
    Neighbour::Neighbour(const NodeID& t_nodeid): Entry
    Neighbour::Neighbour(const NodeID& t_nodeid): Exit
    Neighbour::Neighbour(const Neighbour& neighbour) 192.168.1.4:433
    Neighbour::~Neighbour(): Entry: 192.168.1.4:433
    in list, deleting now
    Neighbour::~Neighbour(): Entry: 192.168.1.4:433
    in list, deleting now
    Segmentation fault
    

    Das heißt er löscht das letzte Element als erstes (warum auch immer) und im nächsten durchlauf taucht dann der seg fault auf. Hab ich irgend etwas vergessen bei der initialisierung des iterators oder so ? Ich kann mir das alles einfach nicht erklären.

    Viele Grüße und vielen Dank im Voraus

    Jan



  • Vergisst es, blödsinniger fehler 🙂

    Jan



  • Erstmal gibt erase() einen Iterator auf das erste nicht gelöschte Element zurück, da ist der Inkrement dahinter überflüssig (und führt dich über kurz oder lang aus dem vector raus). Das könntest du mal kontrollieren, indem du in der Schleife jeweils Position "theIterator-list.begin()" und Größe "list.size()" des Vektors ausgibst.

    Und zweitens löscht der vector Elemente am Anfang der Sequenz, indem er die Nachfolger nach vorne kopiert und anschließend das letzte Element physikalisch löscht - da könnte also auch noch ein Fehler in deinem operator= stecken.



  • Janson schrieb:

    Vergisst es...

    Wer vergisst es ? 😉

    Gruß,

    Simon2.



  • Ich behaupte mit Sicherheit, dass die Ursache des Segfault in dem Inkrement hinter dem Löschen liegt 😉

    1. theIt ist Element 1
    2. Element 1 wird gelöscht
    3. theIt wird zum Element hinter dem gelöschten (also 2) und nochmal inkrementiert (also 3)
    4. Element 3 wird gelöscht
    5. theIt wird zum Element hinter dem gelöschten (also end) und nochmal inkrementiert (also "end+1")
    6. Da "end+1" != end ist terminiert die Schleife nicht und -> bumm (wenn nicht schon die Inkrementierung von end zum Segfault führt spätestens der Zugriff auf das Element)

    EDIT: Und in 5 liegt ein Denkfehler meinerseits - vergesst es :p



  • @CStoll:

    TAUSEND DANK !!!!
    Am operator= hats gelegen 🙂

    Hab an diesen blöden Fehler schon mehrere Tage gehangen.

    VIELEN VIELEN DANK !

    Viele Grüße

    Jan



  • Da der Titel soweit passt, mache ich mal hier weiter mit meiner Frage...
    Also bei mir kommt auch "Segmentation fault" sobald ich beim 'push_back()' ankomme:

    std::vector<IOModule> toGroup, ioModule;
    ...
    std::cout<<moduleArray.size()<<ioModule.size(); // size = 2
    
        for(int i=0; i<moduleArray.size(); i++)
                    if(rectSelect.intersects(moduleArray[i]))                                         
                       toGroup.push_back(ioModule[i]);//Hier kommt Segmentation fault
    

    Übersehe ich irgendwas?



  • Allroad schrieb:

    Da der Titel soweit passt, mache ich mal hier weiter mit meiner Frage...
    Also bei mir kommt auch "Segmentation fault" sobald ich beim 'push_back()' ankomme:

    std::vector<IOModule> toGroup, ioModule;
    ...
    std::cout<<moduleArray.size()<<ioModule.size(); // size = 2
    
        for(int i=0; i<moduleArray.size(); i++)
                    if(rectSelect.intersects(moduleArray[i]))                                         
                       toGroup.push_back(ioModule[i]);//Hier kommt Segmentation fault
    

    Übersehe ich irgendwas?

    Mehrere Fehlerquellen:
    a) Ist moduleArray.size() wirklich immer gleich ioModule.size()?
    (wegen Indexzugriff)
    b) Ist die Klasse IOModule für Kopien vorgesehen?

    Falls du dir unsicher bist solltest du mal mit einem try/catch-Block um die Schleife arbeiten und statt den Indexoperator [i] die Methode at(i) verwenden. Tritt der Fehler dann auch noch auf, oder wurde eine Exception ausgelöst?

    cu André



  • Ok, ich probier das mal aus un melde mich wieder...
    zu a) ja, sind immer gleich gross (vom Typ aber verschieden),
    zu b) ja, die Klasse hat ein CopyConstr.

    aber, es kann sein, dass ich mich geirrt habe und mein Fehler doch von woanders kommt. Bin mir nicht ganz sicher wie ich eindeutig herausfinden kann woher mein Seg. fault kommt...



  • So, hab meine Fehler nun gefunden:

    int size = moduleArray.size();
    for(int i=0; i<size; i++)
    {
    if(rectSelect.contains(moduleArray[i], 0)) // Qt-Befehl, nicht weiter interesant, aber an dieser Stelle kommt mein Problem!!!
      moduleArray.removeAt(i); // auch Qt- Befehl zum Entfernen 
             }
    

    wenn z.B. ich nur zwei Elemente in meinem Vektor habe, wird beim ersten Durchlauf (i=0)das erste Element gelöscht, beim zweiten Durchlauf wird modulArray[1] aufgerufen was nicht mehr existiert...!!! => Segmentation fault 🙄 Trivial eigentlich..
    Dennoch möchte ich irgendwelche Elemente aus meinem Vektor löschen, wie mache ich das am Besten, so dass ich auch die richtige Elemente entferne! (auch wenn ich eine Kopie vom orig.-Vektor mache, sobald ich ein Element rausnehme, ändern sich die Positionen (Indizes) der restlichen Elemente)


Anmelden zum Antworten