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)


Log in to reply