valgrind fehlermeldung / hinweis



  • hallo zusammen,

    ich habe folgenden valgrind output:

    [log]
    ==2608== 760 bytes in 95 blocks are possibly lost in loss record 10,776 of 12,033
    ==2608== at 0x4A085C7: operator new(unsigned long) (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
    ==2608== by 0x46D902: __gnu_cxx::new_allocator<PeerMessage*>::allocate(unsigned long, void const*) (new_allocator.h:88)
    ==2608== by 0x46D92A: std::_Vector_base<PeerMessage*, std::allocator<PeerMessage*> >::_M_allocate(unsigned long) (stl_vector.h:127)
    ==2608== by 0x4A0DC7: std::vector<PeerMessage*, std::allocator<PeerMessage*> >::_M_insert_aux(__gnu_cxx::__normal_iterator<PeerMessage**, std::vector<PeerMessage*, std::allocator<PeerMessage*> > >, PeerMessage* const&) (vector.tcc:275)
    ==2608== by 0x4A101B: std::vector<PeerMessage*, std::allocator<PeerMessage*> >::push_back(PeerMessage* const&) (stl_vector.h:610)
    ==2608== by 0x49F6A0: PeerMessageQueue::add(PeerMessage*) (PeerMessageQueue.cc:110)
    ==2608== by 0x49B8B2: MessageTransfer::send(PeerMessage&) (MessageTransfer.cc:141)
    ==2608== by 0x422037: Dispatcher::sendMessage(PeerMessage&) (Dispatcher.cc:163)
    ==2608== by 0x480865: MembershipService::sendLeaveAnnounceMessage(PeerIDList const&, VirtualLogicalTime const&) (MembershipService.cc:768)
    ==2608== by 0x480E36: MembershipService::sendLeaveAnnounceMessage(unsigned int const&) (MembershipService.cc:755)
    ==2608== by 0x480FE6: MembershipService::leaveGroup() (MembershipService.cc:237)
    ==2608== by 0x421B1C: Dispatcher::leaveGroup() (Dispatcher.cc:316)
    [/log]

    von folgenden Code:
    [c++]
    void
    PeerMessageQueue::add(PeerMessage * pdu) {

    PeerMessage * elem = find(pdu->getMessageReference());

    if (elem == NULL) {
    queue.push_back(pdu->dup());
    }//End if
    }//End add
    [/c++]

    kann mir jemand sagen, was ich falsch gemacht habe???

    danke 😃



  • ach scheiße,

    nochmal bissl hübscher zumindest den code:

    void 
     PeerMessageQueue::add(PeerMessage * pdu) { 
    
     PeerMessage * elem = find(pdu->getMessageReference()); 
    
     if (elem == NULL) { 
     queue.push_back(pdu->dup()); 
     }//End if 
     }//End add
    

  • Mod

    Mehr Kontext. Was ist eine PeerMessage ? Was macht find(pdu->getMessageReference()) ;? Warum ist pdu ein Pointer? Wo kommt der her? Was macht dup() ? Was genau ist queue ? Wo kommt die her?

    Das alles unter der Voraussetzung, dass diese Dinge überhaupt relevant sind, wovon du anscheinend ausgehst, weil du uns den Code gezeigt hast. Wenn du dir nicht sicher bist: Vollständiges Minimalbeispiel konstruieren. Das ist auch eine wunderbare Methode, um Fehler selber zu finden. Siehe dritter Link in meiner Signatur.



  • Ich gehe mal davon aus, dass dup() ein kreativ benamtes clone() sein soll.
    Dort wird also eine neue Instanz mit new erzeugt, welche du nie wieder löschst.
    Fazit: Keine rohen Zeiger auf neu erstellte Objekte zurückgeben und stattdessen Smartpointer benutzen.



  • Obwohl, der Output von valgrind passt nicht ganz zu der Theorie, da das Leak offenbar von std::vector selbst ausgeht.
    Naja, da müssen mehr Informationen her, wie SeppJ schon gesagt hat.


  • Mod

    ;Athar schrieb:

    Obwohl, der Output von valgrind passt nicht ganz zu der Theorie, da das Leak offenbar von std::vector selbst ausgeht.
    Naja, da müssen mehr Informationen her, wie SeppJ schon gesagt hat.

    Genauer gesehen ist das ein vector von Pointern, was auch schon verdächtig ist. Aber noch nicht so verdächtig, als dass ich es ohne Zusatzinformation direkt als Fehler benennen würde.



  • hallo zusammen,

    ich gelobe besserung, mal wieder 😉

    also, das ganze läuft in einem simulator. die peermessage ist eine nachricht, welche erzeugt und zu anderen teilnehmern versendet wird. dup() ist in der tat ein clone, welches return new PeerMessage(this) macht. Ist nicht meine Idee, haben sich die leute vom simulator so ausgedacht und muß man implementieren.

    Die methode add als solches speichert in der queue nachrichten, welche später gelöscht werden. Per find schaue ich, ob diese nachricht schon gespeichert ist. wenn nicht, lagere ich eine kopie dieser ein, da die eigentliche nachricht von der aufrufenden methode gelöscht wird, per delete. smartpointer hätte ich aus heutiger sicht liebend gern verwendet, aber als das programm entstanden ist, kannte ich sowas schlichtweg nicht. 😞 ein umbau ist aber im moment aus zeitgründen nicht drin. valgrind hab ich angeschmissen, da ich irgendwo eine null-pointer zugriff habe, diesen aber nicht finde. ich weiß, auch da wären smart_pointer hilfreich gewesen. 😉


  • Mod

    Dann sit wohl davon auszugehen, dass Athar vollkommen recht hat und die Kopie, trotz deiner Beteuerungen, nicht korrekt freigegeben wird. Das sind halt die typischen Probleme, die man bekommt, wenn man nicht RAII benutzt. Darum nutzt man das schließlich für absolut alle Ressourcenhalter.

    Wie wäre es mit einem großen Refactoring des Programms, anstatt jetzt mit viel Aufwand einen bestimmten Fehler zu jagen und bei der nächsten kleinen Änderung 20 neue zu erzeugen? Von den wenigen Teilen, die du gezeigt hast, braucht es doch bloß eine Umdefinition der Containerklasse. (Oder sind die Datentypen überall hartcodiert, anstatt per typedefs und templates? Das wäre ebenfalls so ein Fall von selbstgemachter Mehrarbeit durch Faulheit beim ersten Entwurf)


Anmelden zum Antworten