避免内存泄漏

时间:2011-03-22 05:37:09

标签: c++ memory memory-leaks

我们如何使用重载运算符来防止C ++中的内存泄漏?

任何完整的例子..

此致

PKV

4 个答案:

答案 0 :(得分:11)

如果您想避免内存泄漏,请不要使用delete

这可能看似矛盾,但事实是手动内存管理容易出错,最好使用自动(或库)技术。

在C ++中,对于您创建的每个对象,应该有明确的所有权。也就是说,您应该能够识别对象的生命周期,可能取决于其他人。

第一步是避免动态内存分配:如果你不使用new,你就没有什么可以管理的 - 警告:一些库会把你的记忆交给你,期待你释放它。因此,只要有可能,使用堆栈

使用STL容器(例如new)而不是滚动自己的情况,可以避免多次使用std::vector<T>

第二步是谨慎使用new,并在分配后立即将内存交给单个所有者。这些所有者包括:

  • std::unique_ptr(C ++ 0x)或boost::scoped_ptr,在最后的手段std::auto_ptr
  • boost::ptr_vector以及Boost.Pointer Container
  • 的整个集合

单个所有者很容易追踪,并且由于对象的生命周期与其所有者相关联,因此对象的生命周期也很容易追踪。

第三步是微妙的,共享所有权的引入。它确实使对象生命周期内的所有推理变得复杂,并且引入了引用循环的风险,这有效地意味着内存泄漏。在某些情况下它们是必需的,但最好尽可能避免。

  • std::shared_ptr(C ++ 0x)或同等版本(std::tr1::shared_ptrboost::shared_ptr
  • std::weak_ptr(C ++ 0x)或同等的

后者用于“打破”循环。但是,即使有关系图,也很难理解在哪里引入weak_ptr

修改

正如托比亚斯所说,这个成语被称为资源获取初始化(RAII),它被命名为笨拙。一个更新的术语正在出现:用于描述其子集的范围绑定资源管理(SBRM) - &gt;将资源绑定到范围。

答案 1 :(得分:2)

只是为Matthieus回答增加一些更多的一般性:

每当您使用需要释放的资源(内存,网络连接,文件句柄,窗口句柄......)时,请使用Resource Acquisition Is Initialization (RAII)

这个成语的一个表现形式是上面提到的std :: unique_ptr和boost :: scoped_ptr。 如果您没有可用资源的RAII容器 - 构建一个。这总是值得的。

答案 2 :(得分:2)

大多数人建议使用Boost或STL,但有些情况是不可能的(在操作系统开发,资源有限的嵌入式系统等)。在这种情况下,请确保尽可能使用堆栈,并且只在类的构造函数中使用new并在其析构函数中使用delete。对于双重检查,有一些工具可以帮助您查找内存泄漏,例如valgrind

答案 3 :(得分:1)

如果您想避免内存泄漏,请不要使用boost.shared_ptr滚动自己的解决方案。如果你真的想手动完成它,那么就把你的清理代码放在析构函数中。