2013-06-28 4 views
9

Ho un costruttore per una classe che inizializza un unique_ptr all'interno di quella classe con un valore passato ad esso. Per qualche ragione, valgrind lamenta una perdita di memoria:Perdita di memoria nonostante l'utilizzo di 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 */ 

Questo è il codice censurato, spogliato di tutto il materiale irrilevante:

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 
{ 
} 

Può spiegare perché e come si verifica la perdita di memoria ?

+1

La memoria per l'oggetto 'VectorBasedNodeOrder' è gestita correttamente? Se questo oggetto è trapelato, valgrind emetterebbe un avvertimento non solo per questo, ma anche per i suoi membri, incluso quello di 'unique_ptr'. – jogojapan

+0

@jogojapan Questo è stato anche il mio primo pensiero, ma valgrind non dovrebbe emettere un avvertimento per l'istanza di 'VectorBasedNodeOrder'? Non è così, questo è l'unico avvertimento "definitivamente perso". – Chris

+0

sì, è giusto, in questo caso dovrebbe esserci un altro avviso. (Avevo dato per scontato che non avresti dovuto ancora guardarlo perché probabilmente sarebbe arrivato più in basso nella lista degli avvertimenti di Valgrind.) Ma quello che Mark B ha appena detto in una risposta potrebbe essere una spiegazione per questo. – jogojapan

risposta

25

In base al commento che le prime Node puntatori sono gestiti altrove e non il problema che ho intenzione di prendere una pugnalata selvaggio che NodeOrder o un ulteriore genitore non hai distruttore virtuale, e quando il vostro VectorBasedNodeOrder è distrutta polimorfico per puntatore della classe base, il distruttore figlio non viene mai chiamato, con la conseguenza che unique_ptr non viene mai distrutto.

+0

'NodeOrder' infatti non aveva un distruttore virtuale. Farà nuovamente il test e farti sapere. – Chris

+2

Questa è una risposta piuttosto perspicace. Ci avrei quasi messo i soldi. – paddy

+0

Anche se sembra molto buono come ipotesi, perderai le scommesse sulla pugnalata selvaggia. – SChepurin