避免内存泄漏 我们如何使用重载操作符来防止C++中的内存泄漏?

避免内存泄漏 我们如何使用重载操作符来防止C++中的内存泄漏?,c++,memory,memory-leaks,C++,Memory,Memory Leaks,任何完整的例子 问候, PKV如果要避免内存泄漏,请不要使用自己的解决方案。如果确实要手动执行,请将清理代码放入析构函数。如果要避免内存泄漏,请不要使用delete 这似乎有些矛盾,但事实是手动内存管理容易出错,最好使用自动(或库)技术 在C++中,对于每个创建的对象,应该有明确的所有权。也就是说,您应该能够识别对象的生命周期,这可能取决于其他一些生命周期 第一步是避免动态内存分配:如果您不使用new,您就没有任何需要管理的东西——警告:某些库会将内存交给您,并期望您释放它。因此,只要有可能,使

任何完整的例子

问候,


PKV

如果要避免内存泄漏,请不要使用自己的解决方案。如果确实要手动执行,请将清理代码放入析构函数。

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

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

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

第一步是避免动态内存分配:如果您不使用
new
,您就没有任何需要管理的东西——警告:某些库会将内存交给您,并期望您释放它。因此,只要有可能,使用堆栈

通过使用STL容器(
std::vector
)而不是滚动您自己的情况,可以避免大量使用
new

第二步是节省地使用
new
,并始终在分配内存后立即将其移交给单个所有者。这些业主包括:

  • std::unique_ptr
    (C++0x)或
    boost::scoped_ptr
    ,在最后的手段
    std::auto_ptr
  • boost::ptr_vector
    和整个库集合
单个所有者很容易跟踪,而且由于对象的生存期与其所有者相关,因此对象的生存期也很容易跟踪

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

  • std::shared_ptr
    (C++0x)或同等标准(
    std::tr1::shared_ptr
    boost::shared_ptr
  • std::weak_ptr
    (C++0x)或同等标准
后者用于“中断”循环。然而,很快就很难理解在何处引入
弱ptr
,即使使用关系图也是如此

编辑:


正如Tobias所指出的,这个习语被称为资源获取即初始化(RAII),它的名称很尴尬。一个较新的术语正在出现:作用域绑定资源管理(SBRM)来描述它的一个子集-->将资源绑定到一个作用域。

只是为了给Matthieus答案增加一些通用性:

无论何时使用需要释放的资源(内存、网络连接、文件句柄、windows句柄等),请使用

这个习惯用法的一个表现就是上面提到的std::unique_ptr和boost::scoped_ptr。
如果您没有可用于所需资源的RAII容器,请构建一个。这总是值得的。

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

嗯,我想您可能会让操作员过载,导致系统关闭或其他情况。您是否考虑了一个特定的场景?您的意思是使用重载的
运算符new
?Boost还提供
使共享
分配共享
,这样您就可以避免使用
新的
。是的,尽管它仍然在引擎盖下使用
新的
。是的,但是所有STL容器都在引擎盖下使用
新的
。还应该注意的是,
placement new
使用起来也很安全,不会导致内存泄漏。哎呀,我太专注了,以至于忘记了习惯用法的名称:D