删除顺序,NULL指针或内存泄漏

Jus*_*tin 1 c++ memory memory-management

我有以下情况:

Foo1 foo1* = new Foo1(...);
Foo2 foo2* = new Foo2(foo1, ...);
Run Code Online (Sandbox Code Playgroud)

要么

Foo1 foo1(...);
Foo2 foo2(foo1, ...);
Run Code Online (Sandbox Code Playgroud)

我需要删除Foo1和Foo2.如果我理解正确,我应该按照分配的相反顺序释放内存.所以我应该这样做:

delete(foo2);
delete(foo1);
Run Code Online (Sandbox Code Playgroud)

但是我不能这样做,因为在foo2的析构函数中foo1被设置为NULL.所以当我尝试删除foo2时,它试图删除一个NULL引用并触发一个断言.有没有解决的办法?这里最好的解决方案是允许我仍然将内存分配给堆栈,但绝对没有必要.


编辑:

看到这个主题:shared_ptr会自动释放内存吗?

感谢您的回复.关于问题是什么(显然)我是错的.我需要在这里使用shared_ptr,因为我无法更改API.

Foo1 *foo1 = new Foo1(...);
shared_ptr<Foo2> foo2(foo1);
Run Code Online (Sandbox Code Playgroud)

这里的shared_ptr是否会处理释放foo1使用的内存?如果我理解正确,我不应该在foo1上调用删除正确吗?

我会问一个单独的问题并链接到它.

akt*_*ton 7

首先,您只需要delete使用创建的对象new.一般来说,对于创建的对象没有顺序依赖性new.但是,可能存在构造函数/析构函数依赖项,例如foo2在foo2的析构函数中调用foo1上的函数.在这种情况下,破坏的顺序很重要.

其次,即使foo2中的foo1指针设置为null,这只是foo2中保存的指针的本地副本.它不会影响指针的其他副本.在foo2中将foo1设置为null并不是一个坏主意,因为它表示不应再使用该对象,但这与调用其析构函数或使用free它不同.


Pup*_*ppy 5

我应该按照分配的相反顺序释放内存.

呃,不是一个通用的分配器,就像一个供电newdelete.

但是我不能这样做,因为在foo2的析构函数中foo1被设置为NULL.

这是一堆巨大的WTF.为什么你会有这样的计划?甚至不要考虑delete你没有的对象new.

只需使用聪明的指针,就像一个理智的人,忘记所有这一切.