可以精确定位那行内存分配没有被释放的内存泄漏检测方案

内存泄漏检测方案

目前我们的对内存的分配/释放多数是采用malloc/free/realloc这一组方函数来做,当然,有些平台这两个函数的名称可能会有点不一样,但接口是一样的,这里我对这个方案的讲解一种简单即十分有效的通过替换malloc/free/realloc三个接口来检测内存泄漏的方案,这种方案可以具体定位到哪一行代码分配到的内存没有被释放掉。

        

         我们知道,malloc分配出来的是一个内存块的起始地址,free释放的时候,也是通过这个地址来进行释放的,realloc对内存进行重新分配时,也是根据这个内存地址,产生一个新的内存块,并返回新内存块的地址,其原理,相当于如下代码:

void * realloc(void * pvMemory, int nNewSize)

{

//这里只是举个示例展示原理,具体在操作系统进行分配时可能会有一些优化,比如,操作系统可以判断,如果旧的内存块大于nNewSize,则可以不用重新分配,但这不会影响我们这个内存泄漏检测方案,因为我们可以认为它是释放,并在原地址上进行申请。

 

//申请一块新的内存

         Void * pvNewMemory = malloc(nNewSize);

         memcpy(pvNewMemorypvMemory, nNewSize);

    //释放掉旧的内存块

         free(pvMemory);

 

         return pvNewMemory;

}

 

因此,只要我们详细的记录下每个次内存的分配和释放的地址,最终就可以得到有哪些指针还没有被释放,并且,多数的c编译器是支持_FILE_ _LINE_这两个宏来得到当前代码行所在的文件位置及在文件的行数,因此,只要在,分配内存时,同时记录这两个值,那么,是不是哪一行内存没有被释放,也就出来了呢?

 

以上方案己经经过实践验证,十分有效。

 

关于以上方案接口设计如下:

 

void * MMT_Alloc(char *pcFile, int nLine, int nSize);

{

    Void * pvMemory = malloc(nSize);

AddMallocRecord(pvMemory , pcFile, nLine);

Return pvMemroy;

}

 

void MMT_Free(void * pvMemory)

{

RemoveMallocRecord(pvMemory);

free(pvMemory);

}

 

void * MMT_Realloc(char *pcFile, int nLine, void * pvMemory, int nNewSize)

{

void *pvNewMemory = realloc(pvMemory, nNewSize);

 

RemoveMallocRecord(pvMemory);

AddMallocRecord(pvNewMemory, pcFile, nLine);

 

return pvNewMemory;

}

 

为了调用方便,我们需要再定义一组与malloc/free/realloc接口类似的宏,这样我们就可以直接替换现有代码的内存分配接口,改动较小,并且,如果提心,这个内存泄漏检测机制会影响系统运行,也可以对调试版和发布版分别编译,产生直接调用系统接口和调用本套接口的不同版本。

 

#ifdef _DEBUG_

//检测接口

#define  XINO_ALLOC(SIZE)  MMT_Alloc(__FILE__, __LINE__, SIZE)

#define  XINO_ReaLLOC(MEMORY,SIZE)  MMT_Realloc(__FILE__, __LINE__, MEMORY, SIZE)

#define  XINO_Free(MEMORY)  MMT_Free(MEMORY)

#else

//系统接口

#define  XINO_ALLOC(SIZE)  malloc(SIZE)

#define  XINO_ReaLLOC(MEMORY,SIZE)  realloc(MEMORY, SIZE)

#define  XINO_Free(MEMORY)  free (MEMORY)

#endif

 

 

实现这套机制时,你可以根据具体使用场景来实现内存分配记录的存储方式,如果对效率要求较高,为了提高效率,我建议,AddMallocRecordRemoveMallocRecord都只是分别记录一条记录,系统运行完后,再用工具进行分析,如果空间有限,则在RemoveMallocRecord时,可以直接删除掉对应的分配记录,这样存储的数据就小很多,但效率相应的,也比较低,目前我们使用的方式就是直接删除的。

 

并且,为了使系统能够更加有效的运行,可以在这套机制中,再添加一些开关,这样就可以在系统运行过程中随时打开和关闭该开关,并且,可以在关闭状态下直接发布到市场,将来产品在市场上出现问题时,如果需要使用,则可以直接打开开关,极其方便。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值