本文介绍,当VC++或者MFC程序,出现内存泄露时,如何快速定位的方法,这种方法有必定的局限性,在注意事项中会给出的。多线程
MFC程序
当MFC程序出现内存泄露时,退出程序时的VS调试输出窗口,通常会有以下显示:函数
上面显示了在程序的哪一个文件的哪行语句,发生了内存泄露,其中:工具
{345}: 表示 内存分配编号.net
normal block:表示 内存块类型,有普通块(普通程序分配)、客户端块(分配基于CObject的内存)和CRT块(库函数内部分配)这几种类型线程
0x0074A030:以16进制形式输出的内存位置调试
40 bytes long: 以字节为单位的内存块大小orm
Data< >CD CD ..:内存块前16个字节的内容,16进制表示。blog
定位内存泄露位置,能够双击泄露信息,也能够在输出窗口 按F4键,跳转到 出错行。内存
在普通VC++程序中,要相似MFC中内存检测的效果,须要作以下操做。get
1. 在头文件中,添加 #include <ctrdbg.h>
2. 在程序入口最开始处,添加 下面两句话便可
_CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF ); //设置调试堆函数跟踪分配的方式
//_CrtSetBreakAlloc(); //这句话,在确实有内存泄露的状况下,给 内存分配编号
3. 按F5,运行程序,等待程序退出后,在输出窗口能够看到下面的状况:
如图所示,程序有两处内存泄露地方,分配编号为 476 和 475,此时,给_CrtSetBreakAlloc()函数传入476参数,再次运行程序,在退出时,会弹出以下窗口:
点击 中断 跳到,_CrtSetBreakAlloc()中断的地方,而后在程序中,经过查看调用堆栈,就能够看到应用程序的哪一次new操做没有执行delete操做。
在中断的同时,也能够从控制台中,看到整个程序析构的顺序,以下图所示:
1. 当程序确认没有内存泄露时,不能够调用_CrtSetBreakAlloc(475),由于,这样会在指定内存分配次数发生时,强制中断程序。
2. 这种检测内存分配的方式,要求,程序在执行过程当中,是可还原的(屡次执行过程的内存分配顺序不会发送变化),这个假设,在多数状况下是成立的,不过,在多线程执行的环境下,有时候难以保证。
3. 对于普通C程序,上述检测方法也是成立的,只不过new换成了malloc,delete换成了free
4. 好比 int *p = new int[4]; delete p; 这种方式的泄露,上述方法是检测不出来,此时,须要cppcheck等更有力的工具来检查。
参考连接:C++调试堆