首页 > 试题广场 >

说一说什么是内存泄露,如何检测

[问答题]

说一说什么是内存泄露,如何检测

推荐

得分点

概念、避免内存泄露、检测

参考答案

标准回答

  1. 内存泄漏(Memory Leak)是指程序中已动态分配的堆内存由于某种原因程序未释放或无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃等严重后果。
  2. 避免内存泄露的方法主要就是要有良好的编码习惯,动态开辟内存空间,及时释放内存。也可以采用智能指针来避免内存泄露。
  3. 可以采用静态分析技术、源代码插装技术等进行检测。常见的一些检测工作有:LCLink、ccmalloc、Dmalloc、Electric Fence、Leaky、LeakTracer、MEMWATCH、Valgrind、KCachegrind等等。

延伸阅读

内存泄露示例代码:

void remodel(std::string & str) {
    std::string * ps = new std::string(str);
    // ...
    str = *ps;
    return;
}

上面的函数每当调用时,该函数都分配堆中的内存,但从不收回,从而导致了内存泄露。解决方案,在 return 语句之前添加 delete 语句释放分配的内存。即使添加了 delete 语句,有时也会有问题:

void remodel(std::string & str) {
    std::string * ps = new std::string(str);
    // ...
    if(...) {
        throw exception();
    }
    str = *ps;
    delete ps;    // 如果产生异常,则不会执行 delete 语句
    return;
}

使用智能指针:

void demo2() {
    unique_ptr<double> ap(new double);
    *ap = 20.5;
}
编辑于 2021-09-15 11:11:48 回复(0)

内存泄漏通常是因为调用了malloc/new等内存申请操作,但是缺少了对应的free/delete。
为了判断内存是否泄漏,我们一方面可以使用Linux环境下的内存泄漏检查工具Valgrind,另一方面我们写代码的时候,可以添加内存申请和释放的统计功能,统计当前申请和释放的内存是否一致,以此来判断内存是否有泄漏。

内存泄漏分类:

  • 堆内存泄漏(heap leak)。堆内存值得是程序运行过程中根据需要分配通过malloc\realloc\new等从堆中分配的一块内存,再完成之后必须要通过调用对应的free或者delete删除。
    如果程序的设计的错误导致这部分内存没有被释放,那么此后这块内存将不会被使用,就会产生Heap Leak。
  • 系统资源泄露(Resource Leak)。主要指程序使用系统分配的资源比如 Bitmap,handle,SOCKET等没有使用相应的函数释放掉,导致系统资源的浪费,严重可导致系统效能降低,系统运行不稳定。
  • 没有将基类的析构函数定义为虚函数。当基类指针指向子类对象时,如果基类的析构函数不是virtual,那么子类的析构函数将不会被调用,子类的资源没有正确的释放,从而造成内存泄漏。
发表于 2023-03-09 22:59:34 回复(0)

内存泄漏通常是因为调用了malloc/new等内存申请操作,但是缺少了对应的free/delete。
为了判断内存是否泄漏,我们一方面可以使用Linux环境下的内存泄漏检查工具Valgrind,另一方面我们写代码的时候,可以添加内存申请和释放的统计功能,统计当前申请和释放的内存是否一致,以此来判断内存是否有泄漏。

内存泄漏分类:

  • 堆内存泄漏(heap leak)。堆内存值得是程序运行过程中根据需要分配通过malloc\realloc\new等从堆中分配的一块内存,再完成之后必须要通过调用对应的free或者delete删除。
    如果程序的设计的错误导致这部分内存没有被释放,那么此后这块内存将不会被使用,就会产生Heap Leak。
  • 系统资源泄露(Resource Leak)。主要指程序使用系统分配的资源比如 Bitmap,handle,SOCKET等没有使用相应的函数释放掉,导致系统资源的浪费,严重可导致系统效能降低,系统运行不稳定。
  • 没有将基类的析构函数定义为虚函数。当基类指针指向子类对象时,如果基类的析构函数不是virtual,那么子类的析构函数将不会被调用,子类的资源没有正确的释放,从而造成内存泄漏。
发表于 2023-10-15 20:55:32 回复(0)