我有以下代码,results in an double free or corruption:
class A{
public:
~A(){
cout<<"delete A"<<endl;
}
};
class Test{
public:
A* a;
~Test(){
cout<<"delete Test"<<endl;
delete a;
}
};
class Test2{
public:
A* a;
~Test2(){
cout<<"delete Test2"<<endl;
delete a;
}
};
int main()
{
A* a=new A();
Test test;
test.a=a;
Test2 test2;
test2.a=a;
return 0;
}
我知道为什么会发生这种情况:首先调用~Test2
删除内存,然后~Test
尝试执行此操作。
但我该如何修复或消除错误?假设我无法修改任何一个类。
答案 0 :(得分:0)
这些类看起来很糟糕,但假设它们只是为了演示一些真实世界的代码,你有一些选择(不会修改类)。
作为proposed in the comments by @Igor,您可以简单地为类提供两个A
的单独实例。然而,这可能适合或可能不适合您的需求,因为它们可能是在同一个实例上工作,但它没有说清楚:
int main()
{
A* a1 = new A();
A* a2 = new A();
Test test;
Test2 test2;
test.a = a1;
test2.a = a2;
}
如果你需要他们在同一个实例上操作,你可以在它破坏之前简单地设置一个nullptr
。更改它们可能更有意义,并自己管理内存:
int main()
{
std::unique_ptr<A> a = std::make_unique<A>();
Test test;
Test2 test2;
test.a = a.get();
test2.a = a.get();
// Use Test etc:
...
test.a = nullptr;
test2.a = nullptr;
// a goes out of scope and cleans itself up
}
根据您的使用情况,您可以进行TestWrapper
课程。这适用于所提供的类,但您提供的两个类可能提供各种不同的功能,在这种情况下,您可以考虑制作T public
:
template <typename T>
struct TestWrapper
{
TestWrapper(A* a) { t.a = a; }
~TestWrapper() { t.a = nullptr; }
private:
T t;
};
int main()
{
std::unique_ptr<A> a = std::make_unique<A>();
{
TestWrapper<Test> test(a.get());
TestWrapper<Test2> test2(a.get());
}
}