1

我有以下情况:

Foo1 foo1* = new Foo1(...);
Foo2 foo2* = new Foo2(foo1, ...);

或者

Foo1 foo1(...);
Foo2 foo2(foo1, ...);

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

delete(foo2);
delete(foo1);

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


编辑:

请参阅此线程:shared_ptr 会自动释放内存吗?

感谢您的回复。我(显然)错了问题所在。我需要在这里使用 shared_ptr 因为我无法更改 API。

Foo1 *foo1 = new Foo1(...);
shared_ptr<Foo2> foo2(foo1);

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

我将作为一个单独的问题提出并链接到它。

4

2 回答 2

7

首先,您只需要delete使用new. 一般来说,由new. 但是,可能存在构造函数/析构函数依赖关系,例如如果 foo2 在 foo2 的析构函数中调用 foo1 上的函数。在这种情况下,破坏顺序很重要。

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

于 2012-10-02T23:21:50.633 回答
5

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

呃,不适用于通用分配器,例如为 and 供电的new分配器delete

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

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

只需像理智的人一样使用智能指针,然后忘记所有这些。

于 2012-10-02T23:21:28.287 回答