2013-06-28 7 views
9

Mam konstruktora klasy, która inicjuje unique_ptr wewnątrz tej klasy z wartości przekazanych do niego. Z jakiegoś powodu, valgrind narzeka wycieku pamięci:Przeciek pamięci pomimo użycia unique_ptr

22,080 (24 direct, 22,056 indirect) bytes in 1 blocks are definitely lost in loss record 6 of 6 
    at 0x4C2C7A7: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) 
    by 0x4A64FB: VectorBasedNodeOrder::VectorBasedNodeOrder(VectorBasedNodeOrder const&) (VectorBasedNodeOrder.cpp:33) 
    /* snip more trace */ 

Jest to rzekomo naruszającego kod, pozbawiony wszelkich nieistotnych rzeczy:

class VectorBasedNodeOrder : public NodeOrder 
{ 
public: 
    VectorBasedNodeOrder(const VectorBasedNodeOrder& order); 
protected: 
    std::unique_ptr<std::vector<Node*>> orderedNodes; 
} 

VectorBasedNodeOrder::VectorBasedNodeOrder(const VectorBasedNodeOrder& order): 
NodeOrder(order), 
orderedNodes(unique_ptr<std::vector<Node*>>(
    new std::vector<Node*>(*(order.orderedNodes)))) // <-- line 33 
{ 
} 

Czy możesz wyjaśnić, dlaczego iw jaki sposób nastąpi wyciek pamięci ?

+1

Czy pamięć dla obiektu 'VectorBasedNodeOrder' jest właściwie zarządzana? Jeśli ten sam obiekt zostanie ujawniony, valgrind będzie ostrzegał nie tylko o tym, ale także o jego członkach, w tym 'unique_ptr' jeden. – jogojapan

+0

@jogojapan To była też moja pierwsza myśl, ale czy valgrind również nie powinien generować ostrzeżenia dla instancji 'VectorBasedNodeOrder'? Nie jest to jedyne "zdecydowanie stracone" ostrzeżenie. – Chris

+0

tak, to prawda, w takim przypadku powinno być inne ostrzeżenie. (Przyjąłem, że po prostu jeszcze na to nie patrzysz, ponieważ prawdopodobnie pojawi się na liście ostrzeżeń valgrind.) Ale to, co Mark B właśnie powiedział w odpowiedzi, może być wyjaśnieniem tego. – jogojapan

Odpowiedz

25

Oparte na Twój komentarz, że surowe Node wskaźniki są zarządzane gdzie indziej, a nie problemu Idę wziąć dziką ukłucie że NodeOrder lub dalej rodzic nie posiada wirtualnego destruktora, a gdy VectorBasedNodeOrder jest zniszczona polimorficznie przez wskaźnik klasy bazowej, destruktor podrzędny nigdy nie jest wywoływany, co powoduje, że unique_ptr nigdy nie ulega zniszczeniu.

+0

'NodeOrder' rzeczywiście nie miał wirtualnego destruktora. Ponownie przeprowadzę test i dam ci znać. – Chris

+2

To dość wnikliwa odpowiedź. Prawie na tym zarabiam. – paddy

+0

Chociaż wygląda to bardzo dobrze jako hipotezy, stracisz zakłady na dziką dźgniętą. – SChepurin