vs2008下MFC内存泄露问题一点经验
网上关于MFC下、及非MFC检测内存泄露的方法很多,当然都是基于陈旧的VC++6.0版本的,虽然和对我用处不大,但是只是让我明白了几点:1.非MFC下需要自己动手添加编写内存检测代码,MFC下其调试输出窗口就可以显示是否有内存泄露问题;2.显示内存泄露的时候,一般有两种情况:
(1)指明泄露代码语句:
g:\circle\2010227\flameui\0901_flamedetect_multhread\flamedetect\flamedetectdlg.cpp(312) : {96352} normal block at 0x02D16928, 256 bytes long.Data: < > 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ,意思是在flamedetectdlg.cpp的312行出现内存泄露,第96352分配的内存没有回收出现泄露,泄露地址在0x02D16928内存单元开始的256 bytes个字节区域;
(2) 没有指明泄露代码语句:
{96352} normal block at 0x02D16928, 256 bytes long.Data: < > 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ,这种情况很棘手,我碰到的刚好是这种情况,这个时候就要借助于调试下“调用栈”窗口,分析窗口里面非系统定义的语句,即自己写的代码。
我使用VS2008 MFC编写代码,(1)打开任务管理器动态的跟踪程序的执行情况,可以大致确定在调试全速执行阶段是否有内存泄露,改方法网上介绍详细不在累述;(2)当我退出执行的程序的时候,VS2008的“输出”窗口,显示:
Detected memory leaks!
Dumping objects ->
g:\circle\2010227\flameui\0901_flamedetect_multhread\flamedetect\flamedetectdlg.cpp(312) : {101122} normal block at 0x02E8B3A8, 256 bytes long.
Data: < > 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
g:\circle\2010227\flameui\0901_flamedetect_multhread\flamedetect\flamedetectdlg.cpp(312) : {101121} normal block at 0x02E8B268, 256 bytes long.
Data: < > 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
g:\circle\2010227\flameui\0901_flamedetect_multhread\flamedetect\flamedetectdlg.cpp(312) : {101120} normal block at 0x02E8B128, 256 bytes long.
Data: < > 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
g:\circle\2010227\flameui\0901_flamedetect_multhread\flamedetect\flamedetectdlg.cpp(312) : {101119} normal block at 0x02E8AFE8, 256 bytes long.
Data: < > 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
。。。。。。
g:\circle\2010227\flameui\0901_flamedetect_multhread\flamedetect\flamedetectdlg.cpp(312) : {51133} normal block at 0x02E8AD68, 256 bytes long.
Data: < > 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
分配从开始到,一直存在内存泄露,这可能就是一个循环中,不断new,然后在使用完后没有delete或者只delete了部分。我双击其中的行,泄露代码确实在一个循环中,现贴出来和大家分享:
short myFget_filename1( char* fdirectoryPath,char* filename_array[], int fileMAXLEN, int& filelength )
{
WIN32_FIND_DATA data; //is FindFirstFile Parameters
HANDLE hFind;
int nnCount;
char filename[256];
memset( filename, 0, 256 );
//由于出现写入冲突错误而加上这句,后来发现filename_array[nnCount]是传递过来的参数,
//故不敢对其delete回收自然,这也就成了内存泄露的根本原因
for (nnCount=0;nnCount<fileMAXLEN;nnCount++)
{
filename_array[nnCount]=new char[256];
memset(filename_array[nnCount], 0, 256 );
}
nnCount=0;
strcpy_s(filename, fdirectoryPath);
strcat_s(filename, "*.tif");
//查找当前目录下的所有文件
hFind = FindFirstFile(filename, &data);
while( hFind != INVALID_HANDLE_VALUE )
{
strcpy( filename_array[nnCount],data.cFileName );
nnCount++;
if( !FindNextFile(hFind, &data) )
{
hFind = INVALID_HANDLE_VALUE;
CloseHandle( hFind );
}
}
filelength=nnCount;
return 1;
}
char* filename_array[50000];
int filelen;
int i=0;
myFget_filename1("../OriginImage/",filename_array,50000,filelen);
//注意:调用Fget_filename函数时,要对第二个参数字符串指针数组初始化
后来将代码更改为:
short myFget_filename1( char* fdirectoryPath,char* filename_array[], int fileMAXLEN, int& filelength )
{
WIN32_FIND_DATA data; //is FindFirstFile Parameters
HANDLE hFind;
int nnCount;
char filename[256];
memset( filename, 0, 256 );
// for (nnCount=0;nnCount<fileMAXLEN;nnCount++)
// {
// filename_array[nnCount]=new char[256];
// memset(filename_array[nnCount], 0, 256 );
// }
nnCount=0;
strcpy_s(filename, fdirectoryPath);
strcat_s(filename, "*.tif");
//查找当前目录下的所有文件
hFind = FindFirstFile(filename, &data);
while( hFind != INVALID_HANDLE_VALUE )
{
strcpy( filename_array[nnCount],data.cFileName );
nnCount++;
if( !FindNextFile(hFind, &data) )
{
hFind = INVALID_HANDLE_VALUE;
CloseHandle( hFind );
}
}
filelength=nnCount;
return 1;
}
char* filename_array[50000];
int filelen;
int i=0;
while (i<50000)
{
filename_array[i]=new char[256];
memset(filename_array[i],0,256);
i++;
}
myFget_filename1("../OriginImage/",filename_array,50000,filelen);
while (i<50000)
{
delete filename_array[i];
filename_array[i]=NULL;
i++;
}
内存泄露为问题得到解决。