【问题标题】:reason for memory leakage in C C++C C++中内存泄漏的原因
【发布时间】:2010-12-15 06:44:17
【问题描述】:

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

【问题讨论】:

  • 前一天晚上啤酒太多?

标签: c++ c memory-management


【解决方案1】:

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

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 个字节)。

【讨论】:

【解决方案2】:

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

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

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

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

【讨论】:

    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

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

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

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

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

      【讨论】:

      • 当然,标准说如果基类的析构函数不是虚拟的,那么它是未定义的行为,所以你正在篡改邪恶,内存泄漏是你最不担心的。至于shared_ptr,它有时很有用,但有更好的智能指针/容器可供日常使用。它当然应该是最后的选择。
      【解决方案5】:

      没有deletenew,没有delete[]new[],没有freemalloc

      说真的,你还想听什么?

      【讨论】:

        【解决方案6】:

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

        【讨论】:

        • 对此的反例是 watson1180 的回答。
        • @Cam:我不这么认为,在 watson1180 的例子中,他忘记打电话给delete(尽管它已经写在代码中了)。
        • @Matthieu:嗯……确实。遗憾的是,我目前无法取消对 beb0 的回答投反对票。
        • @Cam:我在“那里”添加了一个大写字母,应该可以让你改变你的投票:)
        • 另一方面,有些 API 结构很差,文档记录也很差,你不知道什么时候你有责任释放一些资源(因此返回智能指针总是比返回原始指针更可取)来自函数的指针)
        【解决方案7】:

        我很惊讶还没有人提到内存损坏。

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

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

        这会导致切断空闲块链。由于那时其他软件都维护自己的指针,指向它们正在使用的任何块,因此程序似乎运行得很好。

        当然,列表偶尔会缺少几个块,这种泄漏最终耗尽了空闲块,使应用程序饿死。

        【讨论】:

          【解决方案8】:

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

          按下按钮时:

            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
          

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2020-04-17
            • 2016-01-27
            • 2010-11-11
            • 2017-02-18
            • 1970-01-01
            • 2021-09-16
            • 2015-08-06
            相关资源
            最近更新 更多