轻轻松松做内存检测
刚接触C++的时候总感觉内存泄露是很可怕的事,觉得手足无措,直到有一天发现心里的巨石居然是那么小的一个case。
方法一:利用CRT调试堆函数
举例说明:
#ifdef _DEBUG
#define CRTDBG_MAP_ALLOC
#include <crtdbg.h>
#include <stdlib.h>
#define new new(_NORMAL_BLOCK,__FILE__,__LINE__)
#endif
int main()
{
char *p = new char[200];
#ifdef _DEBUG
_CrtDumpMemoryLeaks();
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_REPORT_FLAG | _CRTDBG_LEAK_CHECK_DF);
#endif
return 0;
}
输出信息:
Detected memory leaks!
Dumping objects ->
f:\test\highquality\c++primer\main.cpp(10) : {69} normal block at 0x00396990, 200 bytes long.
Data: < > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD
Object dump complete.
分析:
{xxx} — 表示程序运行后第xxx次内存分配发生了泄漏,即内存分配编号;
xxx block — 表示内存块类型,包括三种:普通(normal)、客户端(client)和运行时(CRT);
at 0x00396990 — 表示发生易做图存地址,用十六进制表示;
xx bytes long — 表示发生易做图存大小;
Data:xxx — 表示内存数据信息,一般输出前16字节的内容。
利用_CrtSetBreakAlloc()设置分配指定的内存时,中断,然后查看调用栈。
#ifdef _DEBUG
#define CRTDBG_MAP_ALLOC
#include <crtdbg.h>
#include <stdlib.h>
#define new new(_NORMAL_BLOCK,__FILE__,__LINE__)
#endif
int main()
{
_CrtSetBreakAlloc(69);
char *p = new char[200];
#ifdef _DEBUG
_CrtDumpMemoryLeaks();
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_REPORT_FLAG | _CRTDBG_LEAK_CHECK_DF);
#endif
return 0;
}
方法二:使用VLD工具
Visual Leak Detector是一款用于Visual C++的免费的内存泄露检测工具。相比较其它的内存泄露检测工具,它在检测到内存泄漏的同时,具有如下特点:
(1).可以得到内存泄漏点的调用堆栈,如果可以的话,还可以得到其所在文件及行号;
(2).可以得到泄露内存的完整数据;
(3).可以设置内存泄露报告的级别;
(4).它是一个已经打包的lib,使用时无须编译它的源代码。而对于使用者自己的代码,也只需要做很小的改动;
(5).他的源代码使用GNU许可发布,并有详尽的文档及注释。对于想深入了解堆内存管理的读者,是一个不错的选择。
1.下载VLD工具 http://www.codeproject.com/tools/visualleakdetector.asp
2.使用 解压之后得到vld.h, vldapi.h, vld.lib, vldmt.lib, vldmtdll.lib, dbghelp.dll等文件。将.h文件和.lib文件拷贝到你要检测的工程文件所在的目录里(只针对此工程),将dbghelp.dll拷贝到你的程序的运行目录下。
3.用法:在包含入口函数的.cpp文件中加入语句#include "vld.h"即可。
编译正确后,在debug方式下运行:查看VC的输出信息:
有内存泄露显示:"WARNING: Visual Leak Detector detected memory leaks!"
没有内存泄露,此输出的信息为:"No memory leaks detected."
4.举例说明:
#include <iostream>
#include <string>
#include "vld.h"
using namespace std;
int main()
{
int *n = new int[10];
string *s = new string("hello!\n");
cout << n;
cout << *s;
return 0;
}
输出信息中包含以下语句:
Visual Leak Detector Version 1.0 installed (multithreaded static).
WARNING: Visual Leak Detector detected memory leaks!
---------- Block 84 at 0x003E6CB8: 32 bytes ----------
Call Stack:
f:\test\highquality\c++primer\main.cpp (10): main
f:\dd\vctools\crt_bld\self_x86\crt\src\crt0.c (327): __tmainCRTStartup
f:\dd\vctools\crt_bld\self_x86\crt\src\crt0.c (196): mainCRTStartup
0x7C817077 (File and line number not available): RegisterWaitForInputIdle
Data:
00 00 00 00 CD CD CD CD 68 65 6C 6C 6F 21 0A 00 ........ hello!..
CD CD CD CD CD CD CD CD 07 00 00 00 0F 00 00 00 ........ ........
---------- Block 83 at 0x003E6C50: 40 bytes ----------
Call Stack:
f:\dd\vctools\crt_bld\self_x86\crt\src\newaop.cpp (7): operator new[]
f:\test\highquality\c++primer\main.cpp (9): main
f:\dd\vctools\crt_bld\self_x86\crt\src\crt0.c (327): __tmainCRTStartup
f:\dd\vctools\crt_bld\self_x86\crt\src\crt0.c (196): mainCRTStartup
0x7C817077 (File and line number not available): RegisterWaitForInputIdle
Data:
CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD ........ ........
CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD ........ ........
CD CD CD CD CD CD CD CD ........ ........
Visual Leak Detector detected 2 memory leaks.
“C++primer.exe”: 已卸载“C:\WINDOWS\system32\dbghelp.dll”
“C++primer.exe”: 已卸载“C:\WINDOWS\system32\version.dll”
Visual Leak Detector is now exiting.
程序“[1740] C++primer.exe: 本机”已退出,返回值为 0 (0x0)。
代码改为:
#include <iostream>
#include <string>
#include "vld.h"
using namespace std;
int main()
{
int *n = new int[10];
string *s = new string("hello!\n");
cout << n;
cout << *s;
delete [] n;
delete s;
return 0;
}
输出信息中包含以下语句:
Visual Leak Detector Version 1.0 installed (multithreaded static).
No memory leaks detected.
“C++primer.exe”: 已卸载“C:\WINDOWS\system32\dbghelp.dll”
“C++primer.exe”: 已卸载“C:\WINDOWS\system32\version.dll”
Visual Leak Detector is now exiting.
程序“[4272] C++primer.exe: 本机”已退出,返回值为 0 (0x0)。
作者:one_in_one
补充:软件开发 , C++ ,