如果我写:
b = new int;
b = new int;
delete b;
我知道delete b;
仅从内存中删除第二个b
。由于此删除后没有指向第一个b
的内容,因此存在内存泄漏。
在这种情况下,我知道有一种方法可以在C#和Java中恢复此泄漏。有没有办法在C ++中恢复此内存泄漏?
选项1。
最简单的方法是完全避免new
和delete
。
而不是:
b = new int; b = new int; delete b;
写:
std::unique_ptr<int> b;
...
b = std::make_unique<int>();
b = std::make_unique<int>();
b
被覆盖或超出范围时,它将释放内存。不需要甚至不需要delete
。请注意,它与Java垃圾收集器非常相似,但大多数时候都足够好。
选项2。
另一种方法是使用add-on garbage collector,但是不建议使用该解决方案。首先,垃圾收集器是保守的,这意味着尽管有垃圾收集器,但仍有可能发生内存泄漏。其次,这些解决方案会使现有的问题变得更糟,因为引入内存时不会注意到和处理内存泄漏。引入后一年处理内存泄漏比引入后一小时处理内存泄漏要困难几个数量级。
NOTE
:使用unique_ptr
不如在C#,Java和Python这样的垃圾收集语言中安全。如果没有明确的所有权模型并且有循环所有权,则失败。如果元素a
具有unique_ptr
至b
,并且b
具有unique_ptr
至a
,则它们将永远不会被释放。因为unique_ptr
会释放析构函数中的对象,所以它们永远不会被释放,但是没有人会调用a
或b
的析构函数。如果没有人调用析构函数,则unique_ptr
将永远不会删除该对象,也永远不会调用另一个对象的析构函数。注2
:有时应使用std::shared_ptr
代替unique_ptr
,但这不能解决循环引用的问题。这仅解决了单个对象的多个所有者的问题。NOTE 3
:由于析构函数中的深度递归,这些智能指针不会降低堆栈溢出的可能性。这可能会在长链表的递归销毁或不平衡的二叉树中发生。在这种情况下使用unique_ptr
只是隐藏了递归正在发生的事实。 我知道有一种方法可以在C#和Java中恢复此内存泄漏