Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Memory leak despite using unique_ptr

I have a constructor for a class that initializes a unique_ptr inside of that class with a value passed to it. For some reason, valgrind complains about a memory leak:

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 */

This is the allegedly offending code, stripped of all the irrelevant stuff:

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

Can you please explain why and how the memory leak occurs?

like image 231
Chris Avatar asked Jun 28 '13 04:06

Chris


People also ask

Can you have memory leaks with smart pointers?

Even when using smart pointers, is it still possible to have memory leak ? Yes, if you are not careful to avoid creating a cycle in your references.

How does a smart pointer prevent memory leaks from occurring?

Smart pointers allow you to forget about manual allocation and can help avoid most memory leaks. On managed platforms, an object gets destroyed when there are no references to it. The garbage collection builds a graph of references to free objects even if they have references to each other.

What happens when unique_ptr goes out of scope?

std::unique_ptr is a smart pointer that owns and manages another object through a pointer and disposes of that object when the unique_ptr goes out of scope. The object is disposed of, using the associated deleter when either of the following happens: the managing unique_ptr object is destroyed.

Does unique_ptr call destructor?

Yes. Well the unique ptr has a function object that by default invokes delete on the pointed to object, which calls the destructor. You can change the type of that default deleter to do almost anything.


1 Answers

Based on your comment that the raw Node pointers are managed elsewhere and not the problem I'm going to take a wild stab that NodeOrder or a further parent doesn't have a virtual destructor, and when your VectorBasedNodeOrder is destroyed polymorphically by base class pointer, the child destructor is never called, resulting in the unique_ptr never being destructed.

like image 101
Mark B Avatar answered Sep 22 '22 06:09

Mark B