英文:
Memory leak using unique pointer and polymorphism
问题
我知道std::unique_ptr
不保证内存安全,尤其在循环依赖的情况下更是如此。然而,在我的情况下,我看不到这个问题。Child
包含 Parent
(或者在多态的情况下是 SecondChild
),但它们都不包含 Child
。
Valgrind 报告了丢失了 4
个字节,所以我认为 SecondChild
没有被销毁。我的代码依赖于多态性,所以我希望能够得到关于重构的建议,而不会改变 Child
中的 Parent*
。
#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;
}
英文:
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;
}
答案1
得分: 7
你的代码存在未定义行为,这是因为父类缺少虚析构函数,而你通过基类指针(即std::unique_ptr<Parent>
)删除了Child
对象(即foo()
中的test
)。
未定义行为意味着任何事情都可能发生。在你的情况下,这会导致内存泄漏。
struct Parent {
// ....
virtual ~Parent() {
//^^^^^^ -----> 必须添加 !!
// ...
}
};
阅读更多:
- https://stackoverflow.com/questions/461203/when-to-use-virtual-destructors
- https://stackoverflow.com/questions/353817/should-every-class-have-a-virtual-destructor
英文:
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:
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论