Kann das hier einen Segfault verursachen?



  • Ich bekomme einen Segmentation Fault. Ich habe eine Vermutung woran es liegen könnte. Ich habe zwei boost::unordered_map Objekte. Die sehen so aus:

    typedef boost::unordered_map<uint32_t, request*, boost::hash<uint32_t> > map;
    map connections;
    typedef boost::unordered_map<std::string, webpage*, boost::hash<std::string> > webpage_map;
    webpage_map webpages;
    
    void methode() {
    webpages.clear();
    
    std::vector<uint32_t> connections_marked_for_deletion;
    
    //... hier werden Objekte aus der Map "connections" zum Löschen markiert die aus irgendwelchen Gründen nicht mehr gültig sind
    
    	//Lösche die Einträge aus der Connections Map
    	for( unsigned int i = 0; i < connections_marked_for_deletion.size(); ++i )
    		connections.erase( connections_marked_for_deletion.at(i) );
    
    //Rest manipuliert weder connections noch webpages map
    }
    

    Okay, in connections werden Pointer auf auf Objekte vom Typ request gespeichert. Wenn ich jetzt ein erase mache, wird dann auch wieder der Speicher unter diesem Pointer wieder freigegeben?


  • Mod

    HändyÄndy schrieb:

    Okay, in connections werden Pointer auf auf Objekte vom Typ request gespeichert. Wenn ich jetzt ein erase mache, wird dann auch wieder der Speicher unter diesem Pointer wieder freigegeben?

    Nein.

    Ansonsten: Debugger? Damit findest du schließlich sofort raus, wo der Fehler liegt und musst nicht rumraten.



  • Hi.
    Sollte:

    for( unsigned int i = 0; i < connections_marked_for_deletion.size(); ++i )
            connections.erase( connections_marked_for_deletion.at(i) );
    

    nicht so aussehen? 😉

    for(vector<deintyp>::iterator it = onnections_marked_for_deletion.begin(); it != connections_marked_for_deletion.end(); )
            it = connections.erase(it);
    

    Iteratoren sind was Feines 😉

    Edit: Ich habe nichts gesagt 🤡

    Gruß



  • Das heißt also, dass ich für jedes request objekt, das ich eigentlich löschen will, immernoch ein seperates delete aufrufen muss?



  • HändyÄndy schrieb:

    Das heißt also, dass ich für jedes request objekt, das ich eigentlich löschen will, immernoch ein seperates delete aufrufen muss?

    Ist ganz einfach: zu jedem new gehört ein delete.



  • Okay, und dann hat webpages.clear() auch keine Auswirkungen auf die Objekte die unter den Pointern liegen, die in webpages gespeichert sind? D.h. diese Map müsste ich dann auch sequentiell durchgehen und jedes Element mit delete löschen?



  • Wie gesagt, zu jedem new gehört ein delete.

    Du könntest es dir auch einfacher machen und auf delete-Orgien verzichten, indem du Objekte statt Zeiger in die Container stopfst; oder falls es nicht ohne geht, kannst du auch schlaue Zeiger nehmen, z. B. boost::shared_ptr; oder gleich einen boost Pointer Container. In allen drei Szenarien sparst du dir die deletes und baust weniger Speicherlecks.



  • HändyÄndy schrieb:

    Okay, und dann hat webpages.clear() auch keine Auswirkungen auf die Objekte die unter den Pointern liegen, die in webpages gespeichert sind? D.h. diese Map müsste ich dann auch sequentiell durchgehen und jedes Element mit delete löschen?

    Richtig. Du musst alles was du mit new angelegt hast auch wieder mit delete löschen. Und alles was du mit new[] anlegst mit delete[].

    Tust du das nicht, dann erzeugst du ein Speicherleak! Da du aber ohnehin boost verwendest kannst du ja evtl. mit scoped_ptr arbeiten. Informiere dich mal darüber. Eventuell kannst du dir das Leben damit einfacher machen.



  • Ich meinte natürlich, wie mein Vorredner bereits vorgeschlagen hat einen shared_ptr.



  • Wenn man keinen geteilten Besitz benötigt, ist shared_ptr eigentlich das falsche Mittel. Für Container würde ich eher Boost.PointerContainer einsetzen, wie schon von Nukularfüsiker erwähnt.


Anmelden zum Antworten