C++代码中的xcode 检查内存泄漏漏检查如何做

在 SegmentFault,学习技能、解决问题
每个月,我们帮助 1000 万的开发者解决各种各样的技术问题。并助力他们在技术能力、职业生涯、影响力上获得提升。
问题对人有帮助,内容完整,我也想知道答案
问题没有实际价值,缺少关键内容,没有改进余地
平时写c++程序,内存泄漏问题都比较难以排查,一般都要等到程序出bug了,才能慢慢的检查出来。
请问sf的各位大神平时如何检测内存泄漏问题,谢谢。
答案对人有帮助,有参考价值
答案没帮助,是错误的答案,答非所问
如果你使用windows平台的开发工具vs。
你可以简单的用以下方式测试内存泄露。
#define _CRTDBG_MAP_ALLOC
#include &stdlib.h&
//在最后引入测试内存工具头文件。
#include &crtdbg.h&
int main(int argc,char** argv)
auto p =new char[1000];
//此句放在结束测试的位置
_CrtDumpMemoryLeaks();
原理是在这个头文件里映射了内存的申请和释放函数。除此之外,还有其他的一些第三方工具比如UMDH,VLD,Purify,BoundsCheck等。
也有同样原理的工具。另外也同样有第三方的工具,比如:valgrind等。
答案对人有帮助,有参考价值
答案没帮助,是错误的答案,答非所问
1) 内存泄漏多半可以通过review代码来发现解决的。
2) 开发时注意资源的生命周期, 使用RAII来管理资源。
3) 使用工具(valgrind)来检测程序的内存分配回收情况。
答案对人有帮助,有参考价值
答案没帮助,是错误的答案,答非所问
正确姿势是写出安全的代码,而不是事后弥补。上C++11,使用智能指针,从此不再为忘记释放指针而烦恼。
答案对人有帮助,有参考价值
答案没帮助,是错误的答案,答非所问
我一般都是用valgrind
同步到新浪微博
分享到微博?
关闭理由:
删除理由:
忽略理由:
推广(招聘、广告、SEO 等)方面的内容
与已有问题重复(请编辑该提问指向已有相同问题)
答非所问,不符合答题要求
宜作评论而非答案
带有人身攻击、辱骂、仇恨等违反条款的内容
无法获得确切结果的问题
非开发直接相关的问题
非技术提问的讨论型问题
其他原因(请补充说明)
我要该,理由是:
在 SegmentFault,学习技能、解决问题
每个月,我们帮助 1000 万的开发者解决各种各样的技术问题。并助力他们在技术能力、职业生涯、影响力上获得提升。使用支付宝扫码领红包,余额宝付款才可以使用红包哦!不要忘记哈。每天扫一次,天天赚红包!!可以将二维码保存到手机,每天直接扫码领红包啦!!&&对于C++的内存泄露,相信大家都不陌生,因为C++的内存分配与释放是靠程序员自己控制的,C++高手从中获得了更好的性能,更大的自由,C++菜鸟的收获则是一遍一遍的检查代码和对C++的痛恨。因此要想成为C++高手,内存管理一关是必须要过的,除非放弃C++,转到Java或者.NET,他们的内存管理基本是自动的,当然你也放弃了自由和对内存的支配权,还放弃了C++超绝的性能。
& 如何检测C++内存泄露,在VS2010中使用时,需加上
#define _CRTDBG_MAP_ALLOC
#include &crtdbg.h&& crtdbg.h的作用是将malloc和free函数映射到它们的调试版本_malloc_dbg和_free_dbg,这两个函数将跟踪内存分配和释放(在Debug版本中有效)_CrtDumpMemoryLeaks();函数将显示当前内存泄露,也就是说程序运行到此行代码时的内存泄露,所有未销毁的对象都会报出内存泄露,因此要让这个函数尽量放到最后。刚刚包含头文件和加宏定义是重载了malloc函数,并没有重载new操作符,所以要自己定义重载new操作符才能检测到泄露内存的申请位置。例如:
#define _CRTDBG_MAP_ALLOC
#include &crtdbg.h&
#ifdef _DEBUG //重载new
#define new new(_NORMAL_BLOCK, __FILE__, __LINE__)
#endif
#include &iostream&
int main(int argc,char** argv)
{
char *str1 = NULL;
char *str2 = NULL;
str1=(char*)malloc(100);
str2=new char[50];
_CrtDumpMemoryLeaks();
return 0;
}运行结果:Detected memory leaks!Dumping objects -&e:\c++\test\内存泄露检测2\main.cpp(13) : {62} normal block at 0x, 50 bytes long.&Data: & & & & & & & & && CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD&e:\c++\test\内存泄露检测2\main.cpp(12) : {61} normal block at 0x0 bytes long.&Data: & & & & & & & & && CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD&Object dump complete.
& 如果你是调用其他文件的函数,而内存泄露是在其中的函数中出现,这是不会检测到泄露内存的申请位置,需要在有问题的文件里加上
#define _CRTDBG_MAP_ALLOC
#include &crtdbg.h&
#ifdef _DEBUG //重载new
#define new new(_NORMAL_BLOCK, __FILE__, __LINE__)
#endif &如果你的文件出现#include &afxwin.h&,上面的代码添加到包含该头文件上面,会报一系列错误,这是因为new宏也在afxwin.h中定义了,导致出现冲突,所以最好是将这段代码放在所有包含头文件的下面,避免刚才的错误。
& 关于内存泄露检测的更多信息,参考http://blog.csdn.net/kangroger/article/details/
微信扫码关注公众号CPP技术网,微信号cpp_coder,关注我们的公众号,阅读更多精彩内容!每天还可以领取大红包哦!!!每天还可以领取大红包哦!!!每天还可以领取大红包哦!!! 文章来源:原创文章版权为网站和作者共同所有,会员文章禁止转载。非会员文章转载做好本文超链接即表示授权转载。通过文章下面的分享按钮可以自由分享所有文章。
当前位置:-> ->上一篇:下一篇:
在线提问 问题标题: 问题描述:(简陋的描述会导致问题被最后回答、没有针对性回答甚至无法解答。请确保问题描述的足够清楚。)Linux下c++程序内存泄漏检测代码范例
Linux下对于程序内存泄漏检测的方法很多,最常用的的莫过于使用valgrind工具。但是valgrind相当于让程序在虚拟机中运行,会带来较大的系统资源开销,还会对程序的运行效率产生较大影响,对于那种资源占用大的程序,如果需要长时间运行才能暴露的泄漏问题,它就显得不太好用。
linux下的c++程序中自己实现一个轻量级的泄漏检测代码其实是比较方便的,下面我就给出一个简单的范例,并作简单的说明。当然,我们还是应该提倡使用共享指针,用共享指针自动管理内存可以避免内存泄漏这样的不必要的麻烦。
基本原理:
1.利用glibc提供的__malloc_hook, __free_hook系列函数对内存分配释放做监控;(详见glibc的官方文档)
2.利用backtrace函数获取函数调用栈,并记录;
3.利用backtrace_symbols对调用栈对应的函数做解析;
进一步处理:
4.使用abi::__cxa_demangle把函数名解析为源代码风格;
5.使用addr2line解析出函数调用栈对应的代码行;
6.对于动态库(.so)中的地址解析,需要先在/proc/&pid&/maps文件中找到动态库映射的基地址,才能做解析。
编译连接参数中使用-g -rdynamic
以上每步具体实现的代码可能都没有达到最优,甚至可能是笨办法,如果有更好的实现方案请直接替换,也欢迎赐教。
示例代码:
leakmom.cpp
/* Prototypes for __malloc_hook, __free_hook */
#include&&malloc.h&
#include&&map&
#include&&utility&
#include&&execinfo.h&
#include&&errno.h&
#include&&&assert.h&
#include&&cxxabi.h&
#include&&sys/types.h&
#include&&unistd.h&
#include&&stdlib.h&
#include&&leakmon.h&
CMutexLock&gLock&;
std::map&&void*,&_PtrInfo&&gPtrInfo&;
std::map&&const&LmCallStack*,&_AllocInfo&,&&__comp&&gLeakInfo;
const&int&LmCallStack::&MAX_STACK_LAYERS&=
/* Prototypes for our hooks. */
static&void&my_init_hook&(&void);
static&void&*my_malloc_hook&(&size_t,&const&void&*);
static&void&my_free_hook&(&void*,&const&void&*);
void&*(*__MALLOC_HOOK_VOLATILE&old_malloc_hook)(&size_t&__size&,&const&void&*)
void&(*__MALLOC_HOOK_VOLATILE&old_free_hook)
(&void&*__ptr&,&const&void&*);
/* Override initializing hook from the C library. */
void&(*__MALLOC_HOOK_VOLATILE&__malloc_initialize_hook)
(&void) =&my_init_hook;
void&my_init_hook&(void)
&&&&old_malloc_hook&=&__malloc_hook&;
&&&&old_free_hook&=&__free_hook&;
&&&&__malloc_hook&=&my_malloc_hook&;
&&&&__free_hook&=&my_free_hook&;
static&void&*my_malloc_hook&(&size_t&size&,&const&void&*caller&)
&&&&void&*result&;
&&&&&&&gLock.lock&();
&&&&/* Restore all old hooks */
&&&&__malloc_hook&=&old_malloc_hook&;
&&&&__free_hook&=&old_free_hook&;
&&&&/* Call recursively */
&&&&result&=&malloc&(size);
&&&&/* Save underlying hooks */
&&&&old_malloc_hook&=&__malloc_hook&;
&&&&old_free_hook&=&__free_hook&;
&&&&/* printf might call malloc, so protect it too. */
&&&&//printf (&malloc (%u) returns %p\n&, (unsigned int) size, result);
&&&&&&&RecordPtr(&result&,&size);
&&&&/* Restore our own hooks */
&&&&__malloc_hook&=&my_malloc_hook&;
&&&&__free_hook&=&my_free_hook&;
&&&&&&&gLock.unlock&();
&&&&return&result&;
static&void&my_free_hook&(&void&*ptr&,&const&void&*caller&)
&&&&&&&gLock.lock&();
&&&&/* Restore all old hooks */
&&&&__malloc_hook&=&old_malloc_hook&;
&&&&__free_hook&=&old_free_hook&;
&&&&/* Call recursively */
&&&&free&(ptr&);
&&&&/* Save underlying hooks */
&&&&old_malloc_hook&=&__malloc_hook&;
&&&&old_free_hook&=&__free_hook&;
&&&&/* printf might call free, so protect it too. */
&&&&//printf (&freed pointer %p\n&, ptr);
&&&&&&&RemovePtr(&ptr&);
&&&&/* Restore our own hooks */
&&&&__malloc_hook&=&my_malloc_hook&;
&&&&__free_hook&=&my_free_hook&;
&&&&&&&gLock.unlock&();
void&RecordPtr&(&void*&ptr,&size_t&size)
&&&&&&&//&
&&&&&&&void&*array&[LmCallStack::&MAX_STACK_LAYERS];
&&&&&&&int&cstSize&=&backtrace(&array,&LmCallStack&::MAX_STACK_LAYERS);
&&&&&&&//&&
&&&&&&&LmCallStack*&callstack&=&new&LmCallStack(array&,&cstSize);
&&&&&&&gLock.lock&();
&&&&&&&std::map&&const&LmCallStack*,&_AllocInfo&,&&__comp&::&iterator&it&=&gLeakInfo.find&(callstack);
&&&&&&&if&(it&!=&gLeakInfo.&end())
&&&&&&&&&&&&&it-&second&.size&+=&size;
&&&&&&&&&&&&&it-&second&.alloc++;
&&&&&&&&&&&&&_PtrInfo&pi&(it-&&first,&size&);
&&&&&&&&&&&&&gPtrInfo[ptr&]
&&&&&&&else
&&&&&&&&&&&&&_AllocInfo&aif&(size,
&&&&&&&&&&&&&std::pair&&std::&map&const&LmCallStack*,&_AllocInfo,&&__comp&::iterator&,&bool&&ret&=&gLeakInfo&.insert(&std::pair&&const&LmCallStack*,&_AllocInfo&&(callstack,&aif));
&&&&&&&&&&&&
&&&&&&&&&&&&&if&(ret&.second)
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&&&&_PtrInfo&pi&(ret.&first-&first&,&size);
&&&&&&&&&&&&&&&&&&&gPtrInfo[ptr&]
&&&&&&&&&&&&}
&&&&&&&&&&&&&else
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&&&&// failed
&&&&&&&&&&&&}
&&&&&&&gLock.unlock&();
void&RemovePtr&(&void*&ptr&)
&&&&&&&gLock.lock&();
&&&&&&&std::map&&void*,&_PtrInfo&::iterator&it&=&gPtrInfo.find&(ptr);
&&&&&&&if&(it&!=&gPtrInfo.&end())
&&&&&&&&&&&&&std::map&&const&LmCallStack*,&_AllocInfo&,&&__comp&::&iterator&itc&=&gLeakInfo&.find(&it-&second&.csk);
&&&&&&&&&&&&&if&(itc&!=&gLeakInfo.&end())
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&&&&itc-&second&.size&-=&it-&second&.size;
&&&&&&&&&&&&&&&&&&&itc-&second&.free++;
&&&&&&&&&&&&&&&&&&&if&(0 == (itc&-&second.&alloc&-&itc&-&second.&free))
&&&&&&&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&&&&&&&&&&assert(0 ==&itc&-&second.&size);
&&&&&&&&&&&&&&&&&&&&&&&&&delete&itc&-&first;
&&&&&&&&&&&&&&&&&&&&&&&&&gLeakInfo.erase&(itc);
&&&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&}
&&&&&&&&&&&&&gPtrInfo.erase&(it);
&&&&&&&gLock.unlock&();
void&Report&()
&&&&&&&char&**strings&=&NULL;
&&&&&&&gLock.lock&();
&&&&&&&__malloc_hook&=&old_malloc_hook&;
&&&&__free_hook&=&old_free_hook&;
&&&&&&&for&(std&::map&&const&LmCallStack&*,&_AllocInfo,&&__comp&::iterator&it&=&gLeakInfo&.begin();
&&&&&&&&&&&&&it&!=&gLeakInfo&.end();
&&&&&&&&&&&&&it++)
&&&&&&&&&&&&&printf(&\n&&);
&&&&&&&&&&&&&printf(&====&&
size: %ld,& allocs: %d,& frees: %d, a-f: %d\n&,&it-&&second.size&,&it-&&second.alloc&,&it-&&second.free&,&it-&second&.alloc-&it-&second&.free&);
&&&&&&&&&&&&&printf(&====&&
stacks back trace:\n&&);
&&&&&&&&&&&&&strings&=&backtrace_symbols&((void**)&it-&first&-&callstack,&it-&first&-&size);
&&&&&&&&&&&&&if&(strings&)
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&&&&for(int&i&=
2;&i&&&it&-&first-&&size;&i&++)
&&&&&&&&&&&&&&&&&&{&//printf(&&&&& %s\n&, strings[i]);
&&&&&&&&&&&&&&&&&&&&&&&&&char&output&[1024]
&&&&&&&&&&&&&&&&&&&&&&&&&memset(output&,
&&&&&&&&&&&&&&&&&&&&&&&&&char&temp&[1024]
&&&&&&&&&&&&&&&&&&&&&&&&&memset(temp&,
&&&&&&&&&&&&&&&&&&&&&&&&&////
&&&&&&&&&&&&&&&&&&&&&&&&&////&&& get real function name
&&&&&&&&&&&&&&&&&&&&&&&&&////
&&&&&&&&&&&&&&&&&&&&&&&&&if&(1 ==&sscanf&(strings[&i],&&%*[^(]%*[^_]%[^)+]&&,&temp))
&&&&&&&&&&&&&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&int&status&;
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&char*&realname&=&abi::__cxa_demangle&(temp,
0, 0, &&status);
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&if&(0 ==&status&)
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&char*&p&=&strchr(&strings[i&],&'(');
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&memcpy(output&,&strings[&i],&p-strings&[i]);
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&sprintf(output&+(p-&strings[i&]),&&(%s+%p)
&&,&realname, ((&void**)it&-&first-&&callstack)[i&]);&//printf(&&&&&
-%s\n&, realname);
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&free(realname&);
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&else
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&char*&p&=&strchr(&strings[i&],&')');
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&memcpy(output&,&strings[&i],&p-strings&[i]+2);
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&&&&&&&&&&else
&&&&&&&&&&&&&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&char*&p&=&strchr(&strings[i&],&')');
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&memcpy(output&,&strings[&i],&p-strings&[i]+2);
&&&&&&&&&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&&&&&&&&&&FILE&*&fp&;
&&&&&&&&&&&&&&&&&&&&&&&&&char&module&[1024]
&&&&&&&&&&&&&&&&&&&&&&&&&memset(module&,
&&&&&&&&&&&&&&&&&&&&&&&&&char*&pm&=&strchr(&strings[i&],&'(');
&&&&&&&&&&&&&&&&&&&&&&&&&memcpy(module&,&strings[&i],&pm&-strings[&i]);
&&&&&&&&&&&&&&&&&&&&&&&&&if&(strstr&(module,&&.so&))
&&&&&&&&&&&&&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&__pid_t&pid&=&getpid();
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&sprintf(temp&,&&grep
%s /proc/%d/maps&,&module,&pid&);
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&///
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&///&&&&&&&&&get library base-map-address
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&///
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&fp&=&popen&(temp,&&r&);
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&if&(fp&)
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&char&baseaddr&[64];
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&unsigned&long&long&base;
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&fgets(temp&,&sizeof(&temp)-1,&fp&);&&//printf(&memmap:
%s\n&, temp);
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&sscanf(temp&,&&%[^-]&,&baseaddr);
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&base&=&strtoll&(baseaddr,&NULL,
16);&//printf(&baseaddr:%s\n&, baseaddr); //printf(& base:0x%llx\n&, base);
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&sprintf(temp&,&&addr2line
-e %s %p&,&module, (void&*)((unsigned&long&long)((void&**)it-&&first-&callstack&)[i]-&base));
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&&&&&&&&&&else
&&&&&&&&&&&&&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&sprintf(temp&,&&addr2line
-e %s %p&,&module, ((void&**)it-&&first-&callstack&)[i]);
&&&&&&&&&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&&&&&&&&&&////
&&&&&&&&&&&&&&&&&&&&&&&&&////&&& get source file name and line number
&&&&&&&&&&&&&&&&&&&&&&&&&////
&&&&&&&&&&&&&&&&&&&&&&&&&fp&=&popen&(temp,&&r&);&&//printf(&cmdline:
%s\n&, temp);
&&&&&&&&&&&&&&&&&&&&&&&&&if&(fp&)
&&&&&&&&&&&&&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&fgets(temp&,&sizeof(&temp)-1,&fp&);&//printf(&&&&&
-%s\n&, temp);
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&strcat(output&,&temp);
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&printf(&&&
-&& %s&&,&output);
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&pclose(fp&);
&&&&&&&&&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&&&&&&&&&&else
&&&&&&&&&&&&&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&printf(&&&
-&& %s\n&&,&output);
&&&&&&&&&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&&&&free(strings&);
&&&&&&&&&&&&&&&&&&&strings&=&NULL&;
&&&&&&&&&&&&}
&&&&&&&__malloc_hook&=&my_malloc_hook&;
&&&&__free_hook&=&my_free_hook&;
&&&&&&&gLock.unlock&();
//////////////////////////////////////////////////////////////////////////
CMutexLock::CMutexLock&()
&&&&&&&pthread_mutexattr_t&&m_attr&;
&&&&&&&pthread_mutexattr_init(&m_attr&);
&&&&&&&pthread_mutexattr_settype(&m_attr&,&PTHREAD_MUTEX_RECURSIVE);
&&&&&&&if&(0 !=&pthread_mutex_init&(&m_mutex&,
&&m_attr))
&&&&&&&&&&&&&printf(&c_lock::c_lock
pthread_mutex_init error&%d&.\n&&,&errno);
&&&&&&&&&&&&&assert(0);
&&&&&&&pthread_mutexattr_destroy(&m_attr&);
CMutexLock::~CMutexLock&()
&&&&&&&if(0 !=&pthread_mutex_destroy&(&m_mutex))
&&&&&&&&&&&&&printf(&c_lock::~c_lock
pthread_mutex_destroy error&%d&.\n&&,&errno);
&&&&&&&&&&&&&assert(0);
CMutexLock::lock&()
&&&&&&&if(0 !=&pthread_mutex_lock&(&m_mutex))
&&&&&&&&&&&&&assert(&c_lock::lock
pthread_mutex_lock &&&& 0);
CMutexLock::unlock&()
&&&&&&&int&iRet&=
&&&&&&&if(0 != (iRet&=&pthread_mutex_unlock(&&m_mutex)))
&&&&&&&&&&&&&printf(&c_lock::unlock
pthread_mutex_unlock ret&%d& error&%d&.\n&,&iRet,&errno&);
&&&&&&&&&&&&&assert(0);
示例代码:
////////////////////////////////////////////////////////////////////////
//&&&&The Executable file MUST be linked with parameter '-rdynamic' !!!
////////////////////////////////////////////////////////////////////////
#pragma&once
#include&&string.h&
#include&&pthread.h&
&&&&&&&&&&&&&&&&&&&&&&&&
class&LmCallStack
&&&&&&&char*&callstack&;&//
pointer to buffer recording callstack addresses
&&&&&&&int&size&;&//
count of call stacks
&&&&&&&static&const&int&MAX_STACK_LAYERS;
&&&&&&&LmCallStack(void&*&csk=&NULL,&int&s=0)
&&&&&&&&&&&&&if&(csk&)
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&&&&callstack&=&new&char[&s*sizeof&(void*)];
&&&&&&&&&&&&&&&&&&&memcpy(callstack&,&csk,&s*sizeof&(void*));
&&&&&&&&&&&&}
&&&&&&&&&&&&&else
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&&&&callstack&=
(char&*)csk;
&&&&&&&&&&&&}
&&&&&&&&&&&&&size&=&s&;
&&&&&&~&LmCallStack()
&&&&&&&&&&&&&if&(callstack&)
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&&&&delete[]&callstack&;
&&&&&&&&&&&&}
&&&&&&&&&&&&&callstack&=&NULL&;
&&&&&&&&&&&&&size&=
class&__comp
&&&&&&&__comp(){};
&&&&&&&bool&operator&()
(const&LmCallStack*&first&,&const&LmCallStack*&second)
&&&&&&&&&&&&&return&((first&-&size&&&second-&size&)
&&&&&&&&&&&&&&&&&&&&&&&&(&first-&size&==&second-&&size&&&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&memcmp(first&-&callstack,&second-&callstack&,&sizeof(&void*)*first&-&size)
&&&&&&&&&&&&&&&&&&&&&&&&);
struct&_PtrInfo
&&&&&&&_PtrInfo(const&LmCallStack*&c=NULL&,&long&s=0)
&&&&&&&&&&&&&csk&=&c&;
&&&&&&&&&&&&&size&=&s&;
&&&&&&&const&LmCallStack&*&csk;
&&&&&&&long&size&;
struct&_AllocInfo
&&&&&&&_AllocInfo(long&s=0,&int&a&=0,&int&f=0)
&&&&&&&&&&&&&size=s&;
&&&&&&&&&&&&&alloc=a&;
&&&&&&&&&&&&&free=f&;
&&&&&&&long&size&;
&&&&&&&int&alloc&;
&&&&&&&int&free&;
class&CMutexLock
&&&&&&&CMutexLock();
&&&&&&~&CMutexLock();
&&&&&&&void&lock&();
&&&&&&&void&unlock&();
&&&&&&&pthread_mutex_t&m_mutex&;
void&RecordPtr&(&void*&ptr,&size_t&size);
void&RemovePtr&(void*&ptr);
void&Report&();
最后给出测试代码作为使用范例:
testso.cpp和testso.h需要编译为动态库(.so),由于测试动态库中的内存分配
testso.cpp源码:
#include &testso.h&
void testsoleak()
char* p = new char[15];
testso.h源码:
void testsoleak();
test.cpp源码:
#include &leakmon.h&
#include &testso.h&
char* func1()
char* p = new char[10];
int main (int argc, char *argv[])
gStartLeakMon = 1;
char* p = new char[3];
for (int i=0; i&10; i++)
p = func1();
for (int i=0; i&5; i++)
testsoleak();
return(0);
没有更多推荐了,
加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!【c++ 内存泄漏检测工具 好用的】 - CSDNC/C++检测内存泄漏的方法
今天在听一个同事做转正答辩的时候,谈到如何在vxWorks代码下还检测内存泄漏,因为公司产品容易出现内在泄漏,而且定位非常困难。这令自己想起以前在ZW时遇到过的一个问题,那时候曾经研究过C语言如何检测内在泄漏的问题。刚好在网上已经有高手已经给出了解决方案,因此在这里转载篇技术文档,做为自己技术积累的点滴,自己看了大概思路,便在30分钟内实现了一个简单的C语言版本。晚上HP回来时,刚好在抱怨他们项目因为出现内在泄漏而无法提测,想明天用我写的这个东西试下,希望这个东西能够真正解决问题,为自己先赞一个,加油!以下为转载地址和全文:
-------------------------------------------------------------------------------------------------------------------------------------------------------------
内存泄漏是C语言编程中一个很常见的问题,而且由于内存泄漏所导致的问题出现较缓慢,所以不容易觉察,所以写一个简单的程序来检测内存泄漏很有必要。
内存泄漏通常是指堆内存的泄漏,也就是通过malloc、calloc函数申请的内存,因此内存泄漏的检测方法核心思想就是通过宏定义自定义内存分配及释放函数来替换用户的malloc、calloc、free等函数。设计数据结构记录内存申请信息,申请内存时,记录并插入到全局的链表中;释放内存时从全局链表中查找对应的记录,并删除。程序结束时,将链表中信息写入文件,并清除链表。
如下所示,通过宏定义替换malloc、calloc、free等函数,并插入__FILE__、__LINE__定位语句位置。
没有更多推荐了,
加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!

我要回帖

更多关于 java 内存泄漏代码 的文章

 

随机推荐