全球旧事资料 分类
INE__替换成一个数字,这个数字就是当前这行代码的行号。在DEBUG_NEW的定义中没有直接使用__FILE__,而是用了THIS_FILE,其目的是为了减小目标文件的大小。假设在某个cpp文件中有100处使用了
ew,如果直接使用__FILE__,那编译器会产生100个常量字符串,这100个字符串都是飧SPANcpp文件的路径名,显然十分冗余。如果使用THIS_FILE,编译器只会产生一个常量字符串,那100处
ew的调用使用的都是指向常量字符串的指针。r
r
r
r
再次观察一下由MFCApplicatio
Wizard生成的项目,我们会发现在cpp文件中只对
ew做了映射,如果你在程序中直接使用malloc函数分配内存,调用malloc的文件名和行号是不会被记录下来的。如果这块内存发生了泄漏,MSCRu
timeLibrary仍然能检测到,但是当输出这块内存块的信息,不会包含分配它的的文件名和行号。r
r
r
r
要在非MFC程序中打开内存泄漏的检测功能非常容易,你只要在程序的入口处加入以下几行代码:r
r
r
r
i
ttmpFlag_CrtSetDbgFlag_CRTDBG_REPORT_FLAGr
r
tmpFlag_CRTDBG_LEAK_CHECK_DFr
r
_CrtSetDbgFlagtmpFlagr
r
r
r
这样,在程序结束的时候,也就是wi
mai
,mai
或dllmai
函数返回之后,如果还有内存块没有释放,它们的信息会被打印到Debug窗口里。r
r
r
r
如果你试着创建了一个非MFC应用程序,而且在程序的入口处加入了以上代码,并且故意在程序中不释放某些内存块,你会在Debug窗口里看到以下的信息:r
r
r
r
47
ormalblockat0x00C91C90200byteslo
gr
r
Data000102030405060708090A0B0C0D0E0Fr
r
r
r
内存泄漏的确检测到了,但是和上面MFC程序的例子相比,缺少了文件名和行号。对于一个比较大的程序,没有这些信息,解决问题将变得十分困难。r
r
r
r
为了能够知道泄漏的内存块是在哪里分配的,你需要实现类似MFC的映射功能,把
ew,maolloc等函数映射到_malloc_dbg函数上。这里我不再赘述,你可以参考MFC的源代码。r
r
由于DebugFu
ctio
实现在MSCRu
timeLibrary中,所以它只能检测到堆内存的泄漏,而且只限于malloc,realloc或strdup等分配的内存,而那些系统资源,比如HANDLE,GDIObject,或是不通过CRu
timeLibrary分配的内存,比如VARIANT,BSTR的泄漏,它是无法检测到的,这是这种检测法的一个重大的局限性。另外,为了能记录内存块是在哪里分配的,源代码必须相应的配合,这在调试一些老的程序非常麻烦,毕竟修改源代码不是一件省心的事,这是这种检测法的另一个局限性。r
r
r
r
对于开发一个大型的程序,MSCRu
timeLibrary提供的检测功能是远远不够的。接下来我们就看看外挂式的检测工具。我用的比较多的是Bou
dsChecker,一则因为它的功能比较全面,更重要r
好听全球资料 返回顶部