在函数中留下指针会导致内存泄漏吗?
Posted
技术标签:
【中文标题】在函数中留下指针会导致内存泄漏吗?【英文标题】: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 containers 或std::string
和RAII,不会有任何泄漏。
当你不执行三规则并且不使用 std::shared_ptr 时,有很多方法可以让你的腿断了。所以不要那样做,伤害会更小。
【参考方案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_ptr
、std::unique_ptr
...)。你应该看看他们。
【讨论】:
以上是关于在函数中留下指针会导致内存泄漏吗?的主要内容,如果未能解决你的问题,请参考以下文章
在静态方法中使用匿名 Lamba 订阅事件会导致内存泄漏吗?