new malloc 内存申请转储

关于内存泄露,大概半年前曾查过一次,也写过总结,但太粗了,现在看来参考价值不怎么大。

 

无论windows的crt库函数方式,如CrtMemState,_CrtMemCheckpoint,_CrtMemeDifference,_CrtDumpMemoryLeaks,_CrtMemDumpAllObjectsSince等,或者windows其他内存泄露的检查工具,甚至是与系统无关的检查方式,只要时源码形势的,一般都是通过替换new,malloc,delete,free的实现。

 

c++中的new可以重载,譬如为

void * operator new(size_t nSize, const char * filename, int nLine)

void * operator new[](size_t nSize, const char * filename, int nLine)

 

在实现中将可以依然调用全局的new,如::operator new 也可使用malloc分配内存,并将得到的地址,new的调用处的文件名,行数保存起来即可,为此可以使用map<void *, XXX>这里XXX为要保存的内容组成的结构。

在delete的实现中可以从map中清除此节点。

如此在一个需要测量的周期之后,没有被delete掉的就扔保留在此map中了,可以通过遍历此马匹得到申请内存的文件名及所在行。

 

但什么时间用重载什么时间不用呢,如果全部用了,必将对头文件中的尤其是系统头文件造成影响。我们只需要在我们的代码中使用即可。如此以来,只需在源文件的include与之后,代码之前添加#define new DBG_NEW即可,其中#define DBG_NEW new(__FILE__,__LINE__)可以预先定义好。

 

 

 

对于malloc则没有重载一回事了,但可以另造一个函数,例如windows crt中的实现

#ifdef  _CRTDBG_MAP_ALLOC

#define   malloc(s)         _malloc_dbg(s, _NORMAL_BLOCK, __FILE__, __LINE__)
#define   calloc(c, s)      _calloc_dbg(c, s, _NORMAL_BLOCK, __FILE__, __LINE__)
#define   realloc(p, s)     _realloc_dbg(p, s, _NORMAL_BLOCK, __FILE__, __LINE__)
#define   _expand(p, s)     _expand_dbg(p, s, _NORMAL_BLOCK, __FILE__, __LINE__)
#define   free(p)           _free_dbg(p, _NORMAL_BLOCK)
#define   _msize(p)         _msize_dbg(p, _NORMAL_BLOCK)

#endif

 

 即通过_malloc_dbg实现的内存分配,_malloc_dbg的实现中调用了_nh_malloc_dbg,后者在一个双向链表_CrtMemBlockHeader中维护这内存的分配与释放。

 

因为_malloc_dbg 与 _nh_malloc_dbg的实现在dbgheap.c文件中,如果想要修改这里面的代码啊,除非重新编译c库,否则并不会生效。

 

我曾试图修改_malloc_dbg,使得对分配指定大小的内存时执行一个打了断点的简单语句,从而方便跟踪,但因为如上原因未能生效,变通的实现是自己在工程中加了_malloc_dbg2  在这个函数内修改,并#define malloc(s) _malloc_dbg2(s,_NORMAL_BLOCK, __FILE__, __LINE__)实现。

 

以上实现,完全可轻易写出不依赖平台的代码的...

 

 

 

值得提醒的是,如果在代码中调用了第三方库,而内存是在里面申请的,则这是跟不到的。近期一个内存泄露,不停的提醒如果平台库中申请的内存是跟不到的,偏偏忘了是openssl的库,到了最后被查出来了才恍然大悟,原来是EVP框架初始化申请了内存却没有cleanup造成的。

openssl有自己的内存维护机制,可以检查并报告内存泄露。以前08,09年左右还研究使用过,现在分析时头脑浮现了两次,却始终没在上面深入,惭愧啊。

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值