实用小代码之内存泄漏检测(二)

来源:互联网 发布:js点击保存图到手机 编辑:程序博客网 时间:2024/05/22 12:35

实用小代码之内存泄漏检测(二)


    继上次 实用小代码之内存泄漏检测 一文。这次继续介绍另一个我平时用于动态监测内存泄漏的代码。

    我这里所说的 动态监测内存泄漏 是指在程序执行时,以替换 malloc 和 free 函数来达到检测内存泄漏的目的,因为内存泄漏的主要来源就是 malloc 和 free 这组函数。相比那些分析源代码的检测工具,动态监测能够很好的检测循环中分配的内存是否被泄露。下面我不想多说,一切以代码来说话。

    这里的代码只是给各位一个抛砖引玉的借鉴。其中还有很多不完善的地方。比如没有多线程锁之类的问题。

/*
    PROGRAMER: Wayne Huang
    DATE: 2008.04.18
    LICENCE: GPL v2.0
*/


#define MMALLOC(s) mm_malloc(s,__FILE__,__LINE__)
#define MFREE(p) mm_free(p,__FILE__,__LINE__)
#define MOUTWE "[%s:%d] {%c} 0x%x "

typedef 
struct mmbs mmbs;
struct mmbs{
  mmbs 
*next;
  
char *file;
  
int line;
  
void *mm;
}
;

static mmbs mhandle={NULL,0,0,0};
mmbs 
*handle=&mhandle;

void *mm_malloc(unsigned int s,char *file,int line);
void mm_free(void *p,char *file,int line);
void mm_exit(int rel);

void *mm_malloc(unsigned int s,char *file,int line){
  mmbs 
*p=malloc(sizeof(mmbs)+s);
  mmbs 
*i=NULL;

  
if(p){
    p
->next=NULL;
    p
->file=file;p->line=line;
    p
->mm=&p[1];
    
    
for(i=handle;i->next;i=i->next);

    i
->next=p;
  }

  
return(p->mm);
}


void mm_exit(int rel){
  mmbs 
*t=NULL;

  
for(t=handle->next;t;t=t->next){
    printf(MOUTWE,t
->file,t->line,'E',(int)t->mm);
  }

  
if(rel){
    t
=handle->next;
    
while(t){
      handle
->next=t->next;
      free(t);
      t
=handle->next;
    }

  }

      
  
return;
}


void mm_free(void *p,char *file,int line){
  mmbs 
*now=handle,*pre=handle;
  
int nf=1;
  
if(p){
    
while(now){
      
if(now->mm==p){
    pre
->next=now->next;
    free(now);
    nf
=0;
    
break;
      }
else{
    pre
=now;
    now
=now->next;
      }

    }

    
if(nf){
      printf(MOUTWE,file,line,
'W',(int)p);
    }

  }

  
return;
}

     用 MMALLOC(size); 替代你原先代码中的 malloc(size); MFREE(p); 替代你原来的 free(p); 然后在程序退出以前 执行函数 mm_exit(1); 就可以查看报告,并将泄漏的内存一并释放。如果需要在代码执行过程中查看内存的分配情况,可以执行 mm_exit(0); 来查看。

    两个函数的不同之处在于,第一个会将未释放的内存释放掉。而第二个只是显示通过函数分配的内存情况。

    对于程序执行过程中的输出 {W} 表示释放了一个没有被申请的内存。而 {E} 表示有内存泄漏的情况。在报告中会指明代码的具体位置等相关信息。


文外音:
    原本在第一篇文章发表后,我曾记得有个人在我的文章留言里用C++写了一长串的代码,大概是我代码的两倍吧,好像还没贴完。来实现类似于我今天写的这点代码实现的功能,我粗略得看了下。其中用了符号的重载之类的。的确,我没有办法在不改变人们编程习惯的情况下用C语言实现更好的动态监测泄漏的代码。

   我个人的观点是,能用10行代码解决的事情,绝对不要用100行代码来解决。


北斗星君(黄庠魁)

 
原创粉丝点击