如何检测内存泄漏

本文详细介绍了三种C++内存泄漏检测工具:_CrtDumpMemoryLeaks、VisualLeakDetector和Tencent tMemMonitor(TMM),分别阐述了它们的工作原理、优缺点以及使用场景,帮助开发者有效检测和定位内存泄漏问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、_CrtDumpMemoryLeaks

C运行库的Debug版本提供了许多检测功能,使得我们更容易的Debug程序,我们会用到里面很重要的几个函数。其中最重要的是 _CrtDumpMemoryLeaks()。使用这个函数,需要包含头文件crtdbg.h。
该函数只在Debug版本才有用,当在调试器下运行程序时,_CrtDumpMemoryLeaks 将在输出窗口中显示内存泄漏信息。

#ifdef _DEBUG
#define DEBUG_CLIENTBLOCK   new( _CLIENT_BLOCK, __FILE__, __LINE__)
#else
#define DEBUG_CLIENTBLOCK
#endif
#define _CRTDBG_MAP_ALLOC
#include <crtdbg.h>
#ifdef _DEBUG
#define new DEBUG_CLIENTBLOCK
#endif

int main()
{
    int *p = new int;
    _CrtDumpMemoryLeaks();
    return 0;
}
原理

在使用Debug版的malloc分配内存时,malloc会在内存块的头中记录分配该内存的文件名及行号。当程序退出时CRT会在main()函数返回之后做一些清理工作,这个时候来检查调试堆内存,如果仍然有内存没有被释放,则一定是存在内存泄漏。从这些没有被释放的内存块的头中,就可以获得文件名及行号。

缺点

只能检测出内存泄漏及其泄漏点的文件名和行号,但是并不知道泄漏究竟是如何发生的、该内存分配语句是如何被执行到的。

二、Visual Leak Detector

Visual Leak Detector是一款用于Visual C++的免费的内存泄露检测工具。
相比较其它的内存泄露检测工具,它在检测到内存泄漏的同时,还具有如下特点:
1、 可以得到内存泄漏点的调用堆栈,如果可以的话,还可以得到其所在文件及行号;
2、 可以得到泄露内存的完整数据;
3、 可以设置内存泄露报告的级别;
4、 它是一个已经打包的lib,使用时无须编译它的源代码。而对于使用者自己的代码,也只需要做很小的改动;
5、 他的源代码使用GNU许可发布,并有详尽的文档及注释。对于想深入了解堆内存管理的读者,是一个不错的选择。

原理

在这之前,我们先来看一下_CrtDumpMemoryLeaks是如何工作的。在使用Debug版的malloc分配内存时,malloc会在内存块的头中记录分配该内存的文件名及行号。CRT会在_CrtDumpMemoryLeaks函数调用的时候来检查调试堆内存,如果仍然有内存没有被释放,则一定是存在内存泄漏。从这些没有被释放的内存块的头中,就可以获得文件名及行号。
这种静态的方法可以检测出内存泄漏及其泄漏点的文件名和行号,但是并不知道泄漏究竟是如何发生的,并不知道该内存分配语句是如何被执行到的。要想了解这些,就必须要对程序的内存分配过程进行动态跟踪。Visual Leak Detector就是这样做的。它在每次内存分配时将其上下文记录下来,当程序退出时,对于检测到的内存泄漏,查找其记录下来的上下文信息,并将其转换成报告输出。

三、tMemMonitor (TMM)

Tencent tMem Monitor是腾讯推出的一款运行时C/C++内存泄漏检测工具。TMM认为在进程退出时,堆内存中没有被释放且没有指针指向的无主内存块即为内存泄漏,并进而引入垃圾回收(GC, Garbage Collection)机制,在进程退出时检测出堆内存中所有没有被引用的内存单元,因而内存泄露检测准确率为100%(官方说明)。不过我自己在使用这些工具和方法的过程中,发现TTM的内存泄漏检测准确率是上述所有方法中最高的,特别程序中使用了libxml2库使用不正确导致的内存泄漏也能检测出来。
但是TTM也有个小缺点,它并不适用于检测小程序。
TMM工具主要包含两部分,第一部分是客户端的检测界面,客户端部分主要负责监控目标进程中的内存行为并计算内存泄漏。检测时只要将被检测程序添加到监控列表中,然后正常运行被检程序即可。

参考文章C++内存泄漏检测工具C++ 内存泄漏检测方法c++内存泄漏检测工具(上)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值