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;
}
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: