C C ++中内存泄漏的原因

时间:2010-12-15 06:44:17

标签: c++ c memory-management

C C ++中内存泄漏的原因是什么? (除了通常分配内存而忘记解除分配)

8 个答案:

答案 0 :(得分:16)

如果在分配和释放之间引发异常,则会发生内存泄漏。

void f1() {
    int* ptr = new int;

    // do something which may throw an exception

    // we never get here if an exception is thrown
    delete ptr;
}

每次 f1 以异常终止时,会泄漏4个字节(假设 int 为4个字节)。

答案 1 :(得分:13)

当您分配内存,尚未取消分配内存时会导致内存泄漏,并且您将无法再释放内存,因为您无法再访问它

例如,以下代码导致大小为sizeof(int)的内存泄漏:

int * a = malloc(sizeof(int)); //allocate memory
a = 0; //this will cause a memory leak

这会造成内存泄漏,因为现在我们永远无法释放为a分配的内存。

答案 2 :(得分:6)

如果不释放其他资源(如不在FILE *或其他库句柄上调用fclose),也可能会泄漏内存,因为它们可以分配程序无法直接访问的内存缓冲区。

答案 3 :(得分:4)

假设您创建了一个继承了其他没有虚析构函数的类的类。如果指向此类的指针的类型不是最派生的类(这通常在使用抽象工厂时发生),那么只会调用指针类型中的析构函数,并且您希望在大多数派生函数中释放任何内容类析构函数会泄漏。

这是一个非常常见的错误,有时很难看到。

无论如何,如果你想用C ++避免内存泄漏,请遵循以下规则:

  • 首选传递引用而不是指针
  • 尽可能使用智能指针(请参阅:shared_ptr

答案 4 :(得分:2)

new没有deletenew[]没有delete[]malloc没有free

说真的,你还想听到什么?

答案 5 :(得分:2)

除了你提到的那个之外,没有其他原因导致内存泄漏

答案 6 :(得分:1)

我很惊讶没有人提到内存腐败。

我记得有一个案例,当我们有一个粗略的固定大小的块内存分配器实现为链表。

有些人搞乱了大小计算,导致复制数据只比最大块大小多几个字节(指针当时只有2个字节长:))。然后它将覆盖位于下一个空闲块开头的“下一个”链接,其中垃圾恰好用零填充。

这导致了切断自由区块链的后果。从那时起,其他软件保留了他们自己指向他们使用的任何块的指针,程序似乎运行得很好。

但当然,这个名单偶尔会出现几个街区,这次泄漏最终会耗尽免费区块,使应用程序挨饿。

答案 7 :(得分:0)

以下以伪代码编写的示例旨在说明内存泄漏是如何产生的,以及它的影响,而无需任何编程知识。在这种情况下,程序是一些非常简单的软件的一部分,旨在控制电梯。当电梯内的任何人按下楼层按钮时,程序的这一部分就会运行。

按下按钮时:

  Get some memory, which will be used to remember the floor number
  Put the floor number into the memory
  Are we already on the target floor?
    If so, we have nothing to do: finished
    Otherwise:
      Wait until the lift is idle
      Go to the required floor
      Release the memory we used to remember the floor number

如果要求的楼层数与电梯所在的楼层相同,则会发生内存泄漏;释放内存的条件将被跳过。每次出现这种情况时,都会泄漏更多内存。