Search code examples
c++oopmemory-leakssmart-pointersunique-ptr

Memory leak using unique pointer and polymorphism


I know that std::unique_ptr doesn't guarantee memory safety and especially it is true in the case of circular dependency. However, in my case, I can't see it. Child contain Parent(or SecondChild in case of polymorphism), but neither of them contains Child.

Valgrind reports 4 bytes lost so I suppose that SecondChild was not destroyed. My code really relies on polymorphism so I hope to get advice on refactoring that won't change Parent* in Child.

#include <iostream>
#include <memory>
using namespace std;

struct Parent
{
    Parent() {
        cout << "Expr created" << endl;
    }

    ~Parent() {
        cout << "Expr destroyed" << endl;
    }
};

struct Child : public Parent 
{
    std::unique_ptr<Parent> content;
};

struct SecondChild : public Parent 
{
    int val;
};

std::unique_ptr<Parent> foo()
{
    auto test = make_unique<Child>();
    auto content_in_child = make_unique<SecondChild>();
    content_in_child->val = 4;
    test->content = std::move(content_in_child);
    return test;
}

int main()
{
    std::unique_ptr<Parent> high = foo();
    return 0;
}

Solution

  • You have undefined behavior, due to the fact that the parent class is missing a virtual destructor, and you are deleting Child objects (i.e. test from foo()) through base class pointers (i.e. std::unique_ptr<Parent>).

    Undefined behavior means that anything can happen. In your case, it is a memory leak. Fix it by adding a virtual destructor.

    struct Parent {
         // ....
        virtual ~Parent() {
        //^^^^^^              -----> required !!
        // ...
        }
    };
    

    Read more: