r
r
r
r
ETestMemLeakTestDlgcpp7059
ormalblockat0x00881710200byteslo
gr
r
Dataabcdefghijklm
op6162636465666768696A6B6C6D6E6F70r
r
r
r
第一行显示该内存块由TestDlgcpp文件,第70行代码分配,地址在0x00881710,大小为200字节,59是指调用内存分配函数的Requestorder,关于它的详细信息可以参见MSDN中_CrtSetBreakAlloc的帮助。第二行显示该内存块前16个字节的内容,尖括号内是以ASCII方式显示,接着的是以16进制方式显示。r
r
r
r
一般大家都误以为这些内存泄漏的检测功能是由MFC提供的,其实不然。MFC只是封装和利用了MSCRu
timeLibrary的DebugFu
ctio
。非MFC程序也可以利用MSCRu
timeLibrary的DebugFu
ctio
加入内存泄漏的检测功能。MSCRu
timeLibrary在实现mallocfree,strdup等函数时已经内建了内存泄漏的检测功能。r
r
r
r
注意观察一下由MFCApplicatio
Wizard生成的项目,在每一个cpp文件的头部都有这样一段宏定义:r
r
r
r
ifdef_DEBUGr
r
defi
e
ewDEBUG_NEWr
r
u
defTHIS_FILEr
r
staticcharTHIS_FILE__FILE__r
r
e
difr
r
r
r
有了这样的定义,在编译DEBUG版时,出现在这个cpp文件中的所有
ew都被替换成DEBUG_NEW了。那么DEBUG_NEW是什么呢?DEBUG_NEW也是一个宏,以下摘自afxh,1632行r
r
r
r
defi
eDEBUG_NEW
ewTHIS_FILE__LINE__r
r
r
r
所以如果有这样一行代码:r
r
r
r
charp
ewchar200r
r
r
r
经过宏替换就变成了:r
r
r
r
charp
ewTHIS_FILE__LINE__char200r
r
r
r
根据C的标准,对于以上的
ew的使用方法,编译器会去找这样定义的operator
ew:r
r
r
r
voidoperator
ewsize_tLPCSTRi
tr
r
r
r
我们在afxmemcpp63行找到了一个这样的operator
ew的实现r
r
r
r
voidAFX_CDECLoperator
ewsize_t
SizeLPCSTRlpszFileNamei
t
Li
er
r
r
r
retur
operator
ew
Size_NORMAL_BLOCKlpszFileName
Li
er
r
r
r
r
r
void__cdecloperator
ewsize_t
Sizei
t
TypeLPCSTRlpszFileNamei
t
Li
er
r
r
r
…r
r
pResult_malloc_dbg
Size
TypelpszFileName
Li
er
r
ifpResultNULLr
r
retur
pResultr
r
…r
r
r
r
r
r
第二个operator
ew函数比较长,为了简单期间,我只摘录了部分。很显然最后的内存分配还是通过_malloc_dbg函数实现的,这个函数属于MSCRu
timeLibrary的DebugFu
ctio
。这个函数不但要求传入内存的大小,另外还有文件名和行号两个参数。文件名和行号就是用来记录此次分配是由哪一段代码造成的。如果这块内存在程序结束之前没有被释放,那么这些信息就会输出到Debug窗口里。r
r
r
r
这里顺便提一下THIS_FILE,__FILE和__LINE__。__FILE__和__LINE__都是编译器定义的宏。当碰到__FILE__时,编译器会把__FILE__替换成一个字符串,这个字符串就是当前在编译的文件的路径名。当碰到__LINE__时,编译器会把__Lr