【问题标题】:Order of delete, NULL pointer or memory leak删除顺序、NULL 指针或内存泄漏
【发布时间】:2012-10-02 23:19:23
【问题描述】:

我有以下情况:

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 引用并触发断言。有没有解决的办法?这里最好的解决方案是让我仍然将内存分配给堆栈,但绝对没有必要。


编辑:

看到这个帖子:Will a shared_ptr automatically free up memory?

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

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

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

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

【问题讨论】:

  • 您不应该将delete 与您提供的第二段代码一起使用。如果您需要动态分配它,请使用智能指针并完全忘记删除。
  • @chris 我不能使用第二部分,因为在后台释放会触发断言,因为 Foo2 类中指向 foo1 的指针在尝试释放 foo1 的内存时为 NULL。

标签: c++ memory memory-management


【解决方案1】:

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

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

【讨论】:

  • 谢谢。我用一个(希望如此!)更明智的问题更新了我的问题:)
【解决方案2】:

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

呃,不是用于通用分配器,例如为 newdelete 供电的分配器。

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-06-14
    • 2019-03-31
    • 1970-01-01
    • 2013-11-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多