【问题标题】:does leaving pointers in functions cause memory leaks?在函数中留下指针会导致内存泄漏吗?
【发布时间】:2016-03-16 07:41:58
【问题描述】:

假设我有一个函数或类维护一些指向其他数据对象的指针,如下所示:

class MyObject {
    ...
    AnotherObject* o1, *o2;
    SomeObject* s1, *s2;
    ...
}

int main() {
    ...
    MyObject mo1 = new MyObject();
    ... // do stuff with mo1
    delete mo1;
}

假设它们在初始化期间/之后从其他地方分配了有效的指针值。

当我在内部分配这些指针后销毁 MyObject 对象时,如果我在销毁期间不将指针设为空,是否会导致内存泄漏?:

MyObject::~MyObject() {
    o1 = nullptr;
    o2 = nullptr;
    ...
}

谢谢。

【问题讨论】:

  • 只要每个new 都与delete 配对,是否清空指针对象并没有什么区别。只要您不尝试使用它们,您就会得到不同类型的错误。
  • 你应该发布整个MyObject类,否则很难说。
  • 如果你使用new(或new[])但没有对应的delete(或delete[]那么你有内存泄漏。仅具有非空指针不会导致泄漏。然而,有一种更简单的方法可以避免内存泄漏:不要自己使用指针或动态分配。尽可能使用standard containersstd::stringRAII,不会有任何泄漏。
  • 当你不执行三规则并且不使用 std::shared_ptr 时,有很多方法可以让你的腿断了。所以不要那样做,伤害会更小。

标签: c++ pointers memory-leaks


【解决方案1】:

不,它不会导致内存泄漏。但是请注意:

MyObject mo1 = new MyObject();
// do stuff with mo1
delete mo1;

如果do stuff with mo1 抛出异常(如果它包含对nullptr 的引用,则可能是这种情况)将导致内存泄漏。因此,建议不要像您那样使用裸指针,而是使用智能指针——这样 RAII 可以保证您的指针将被删除。

【讨论】:

  • 谢谢!当我写这个问题时,我并不担心do stuff with mo1 会做什么,但无论如何它绝对值得考虑!
【解决方案2】:

听起来您来自 Java 背景,需要将指针设置为 null 以允许垃圾收集器回收其他对象。如果是这样,答案很简单:不,这不是它在 C++ 中的工作方式。将指针设置为 null 对内存使用没有任何影响,并且无论如何都没有可以回收任何内存的垃圾收集器。

相反,您应该考虑所有权。大多数对象都有一个特定的所有者;一旦该所有者被删除,其拥有的对象也会被删除。这最方便地使用 unique_ptr 而不是原始指针建模。对于拥有更复杂所有权的对象,有 shared_ptr 和 weak_ptr。

再一次,没有垃圾收集器,所以任何时候你使用new创建一个对象,不知何故,某处必须有一个对应的delete。确保不会忘记此类删除的最简单方法是使用 unique_ptr。

还要警惕过于频繁地使用new。您的mo1 对象可以毫无问题地分配到堆栈上:它的生命周期仅限于一个函数(main),所以为什么不使用简单地将其分配为MyObject mo1; - 就足够了,无需新建或删除任何东西。

【讨论】:

    【解决方案3】:

    不,它不会。内存泄漏的发生是因为使用new 分配的未删除内存。清空指针只是以后检查它是否被删除的一种方式,它与内存泄漏无关。

    另一方面,手动处理内存并不是实现您想要的最佳方式。存在智能指针(std::shared_ptrstd::unique_ptr...)。你应该看看他们。

    【讨论】:

      猜你喜欢
      • 2021-06-14
      • 2012-08-10
      • 2023-03-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-23
      • 2021-09-25
      • 2014-12-08
      相关资源
      最近更新 更多