最常见的内存/资源泄漏错误

时间:2009-08-26 06:21:03

标签: c++ memory-leaks

所有优秀的C ++程序员都知道如何避免泄漏内存(或套接字等资源):

  1. 始终使用智能指针,i。 e。:std::auto_ptrboost::shared_ptr
  2. 始终了解对象的所有权:谁拥有,谁引用,谁负责等等。
  3. 但是,内存泄漏仍然存在。发现时指出最常见的问题 程序中的内存泄漏,即使您使用了上述技术。

    我开始:

    有时您忘记将基类的析构函数定义为虚拟。所以派生类引用的所有派生类都没有被正确销毁并因此泄露。

5 个答案:

答案 0 :(得分:5)

除了泄漏之外,还有更多类型的错误。按从最坏到最好的顺序:

内存损坏。

数据存储在不应该存在的区域。这导致大多数安全问题是最难追查的。

  • “随机位置”损坏
    • 数据存储在用户可以控制的内存位置。
    • 数据存储到数组而不检查索引。
    • X派生的类型的对象存储到为基本类型X保留的数组元素,X的大小大于其基数的大小
  • 终身腐败
    • 数据在释放后存储到内存位置。
    • 使用了错误的释放方法(不匹配导致new / freemalloc / delete
    • deletefree在同一指针上调用两次。

无法释放内存

程序不再使用的内存仍然已分配。

  • 使用了错误的释放方法:不匹配导致new[] / delete而不是new[] / delete[]
  • 由于引用计数方案中的循环引用,内存不会自动释放,例如在循环数据结构中使用smart_ptr时可能会发生,而不会将weak_ptr用于循环链接。
  • 由于指针丢失而未释放内存 - 在调用free之前,内存的最后一个指针已被清除,因此无法释放它。
  • 由于无法正确识别不再需要内存数据,因此无法释放内存。一个例子是用于某些临时任务的静态缓存永远不会被清除。

答案 1 :(得分:2)

循环引用很常见,std::auto_ptrboost::shared_ptr无法解决这些问题。 你的名单上的(2)没有替代品,它正在使用你的大脑。

答案 2 :(得分:2)

  • 从基类析构函数中调用类似“cleanup”的虚函数。您可能只执行一次...(在基类的析构函数中没有更多的多态性)
  • 没有清理stl :: multimap(没有删除,只插入),并想知道为什么你的程序会继续变慢。

答案 3 :(得分:1)

熟悉自动垃圾收集的人(通过智能指针)所犯的错误:

class A { 
public:
    int avery_useful_calculation()const { return 4; } 
private:
    // class shouldn't be instantiated as an automatic variable (on stack)
    virtual ~A(){} 
};

// client code: needs a very useful calculation

int i = (new A)->avery_useful_calculation();

答案 4 :(得分:0)

也许我超出范围,但我有一些奇怪的错误试图“删除”未初始化的指针。

为了“避免”内存泄漏,如果实现了,我使用try {} __finally {}结构(但是如果在子子调用中引发异常,我会在某处读取它可能是低效的)