zoukankan      html  css  js  c++  java
  • 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++;
     }

    内存泄露为问题得到解决。

  • 相关阅读:
    [GO] go使用etcd和watch方法进行实时的配置变更
    [GO]go context的deadline方法
    [GO]go使用contextCancel
    [GO]go使用etcd
    js控制复选框checkbox 只能单选
    JQuery.Ajax之错误调试帮助信息
    SQLServer2005创建定时作业任务
    JS/JQuery针对不同类型元素的操作(radio、select、checkbox)
    SQL Server跨库查询
    javax.net.ssl.SSLHandshakeException(Cas导入证书)
  • 原文地址:https://www.cnblogs.com/zhwl/p/2759087.html
Copyright © 2011-2022 走看看