C++程序中内存泄漏的几个小工具和方法
内存泄漏,通常被定义为没有释放之前分配的内存资源,在C++的程序中这个问题特别难排查。一个很小的内存泄漏可能在初期没怎么重视,当时累计多了,会造成大面积的崩溃行为和性能问题,很典型的原型就是因为没有释放,内存被用完了。更糟糕的是,有可能还会引起其余的程序访问无效的内存区域,导致困惑的错误。最后都不知道问题出在哪个程序,或者模块中。
在Linux下和Windows下分别有不同的静态,动态检测,分析工具排查此类问题。这里简单介绍几个:
在VisualStudio中可以使用C Run-time (CRT) 库来侦测内存泄漏。
- 在程序开始的位置,或者对应合适的位置,使用如下代码
必须保持Inlcude的顺序
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
- _CRTDBG_MAP_ALLOC宏定义,让CRT的堆功能使用对应Debug版本
- 其中crtdbg.h头文件,让malloc/free使用其debug版本,malloc_dbg/free 可以跟踪内存的分配和销毁,这个行为只在定义了宏_DEBUG的调试模式有效。
- 在程序结束的位置调用如下函数,
_CrtDumpMemoryLeaks();
如果有多个结束的地方,可以在开始的位置定义如下标记位,这样它会自动捕捉到出口位置,然后去调用CrtDumpMemoryLeaks()
_CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
默认情况下,CrtDumpMemoryLeaks函数会将泄漏信息输出到【输出】窗口。
如果是一个库,可以使用如下函数,设置默认位置为【输出】窗口
_CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_DEBUG );
最后输出的内容可能大致如下:
这种方法的具体参考地址:
基于上述的原理,有一个VLD的库,下载地址:
https://kinddragon.github.io/vld/
下载下来后,使用超级方便,直接在你程序开始的代码中
#include “vld.h” 即可。(至于这个VLD.h就是库中的头文件,引用目录后使用即可)。
它的输出信息大约如下:
可以看到内存泄漏的内容,发生的文件信息等。
此外还有很多的C++静态分析工具,有时候也能提供一点建议和信息,比如CppCheck
官网地址: http://cppcheck.sourceforge.net/
使用方式很简单,打开GUI界面后,打开目标项目,点击【扫描】或Analyze即可。几分钟后就可以看到各种问题程度等级的信息。从个人角度来看,效果不是特别大,当时作为一定程度的辅助还是可以试着看看的。
还有一个腾讯的开源静态扫描,支持C++/GO等语言。
地址: https://github.com/Tencent/TscanCode
获取下来后,针对各平台有安装,安装后使用。(源代码编译貌似少一个config.h文件)
菜单按钮选择【扫描文件夹】或文件,几分钟后,弹出了结果窗口,如下图:
相对来说,也是只能作为一个参考。