最近发现程序里有内存泄露,搜索了一下检查内存泄露的工具。
查到了这个工具,下载使用了一下,觉得对小程序还是挺好用的,但是对稍微大一点的程序就比较麻烦了,信息比较混乱,很难看出具体的问题来。
比如:
/*new2.cpp*/#include "stdio.h"int main(){ char* a = new char[100];}注意g++的时候带上-g 调试信息
valgrind --tool=memcheck --leak-check=full ./a.out==8102== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 15 from 1)
==8102== malloc/free: in use at exit: 100 bytes in 1 blocks.==8102== malloc/free: 1 allocs, 0 frees, 100 bytes allocated.==8102== For counts of detected errors, rerun with: -v==8102== searching for pointers to 1 not-freed blocks.==8102== checked 91,884 bytes.==8102== ==8102== 100 bytes in 1 blocks are definitely lost in loss record 1 of 1==8102== at 0x40057F5: operator new[](unsigned) (vg_replace_malloc.c:195)==8102== by 0x8048460: main (new2.cpp:4)==8102== ==8102== LEAK SUMMARY:==8102== definitely lost: 100 bytes in 1 blocks.==8102== possibly lost: 0 bytes in 0 blocks.==8102== still reachable: 0 bytes in 0 blocks.==8102== suppressed: 0 bytes in 0 blocks.==8102== Reachable blocks (those to which a pointer was found) are not shown.int main()
{ char* a = new char[100]; delete a;}那么==8114== Mismatched free() / delete / delete []==8114== at 0x4004CF1: operator delete(void*) (vg_replace_malloc.c:244)==8114== by 0x804849E: main (new2.cpp:5)==8114== Address 0x4020028 is 0 bytes inside a block of size 100 alloc'd==8114== at 0x40057F5: operator new[](unsigned) (vg_replace_malloc.c:195)==8114== by 0x8048490: main (new2.cpp:4)==8114== ==8114== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 15 from 1)==8114== malloc/free: in use at exit: 0 bytes in 0 blocks.==8114== malloc/free: 1 allocs, 1 frees, 100 bytes allocated.int main()
{ char* a = new char[100]; delete[] a;}那么==8126== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 15 from 1)==8126== malloc/free: in use at exit: 0 bytes in 0 blocks.==8126== malloc/free: 1 allocs, 1 frees, 100 bytes allocated.
哈,是不是很好用。但是问题来了。如果你把内存分配写在子线程里,它无论如何也检查不出来。而且无论你的子线程干了什么,它都会傻乎乎的汇报可能有问题。valgrind --tool=memcheck --leak-check=full --trace-children=yes ./a.out
增加参数 --trace-children=yes 追踪子线程。void* thread_test(void* arg)
{ while(1){printf("sleep\n");sleep(1);}}int main()
{ pthread_t thread1; pthread_create(&thread1,NULL,thread_test,NULL); sleep(3); pthread_cancel(thread1); return 0;}子线程里没有任何分配内存,那么结果是什么呢?
==8492== 144 bytes in 1 blocks are possibly lost in loss record 2 of 3==8492== at 0x40046FF: calloc (vg_replace_malloc.c:279)==8492== by 0x4A2E49E9: _dl_allocate_tls (in /lib/ld-2.5.so)==8492== by 0x4A4649D6: (in /lib/libpthread-2.5.so)==8492== by 0x8048573: main (new2.cpp:14)==8492== ==8492== LEAK SUMMARY:==8492== definitely lost: 0 bytes in 0 blocks.==8492== possibly lost: 144 bytes in 1 blocks.==8492== still reachable: 1,052 bytes in 2 blocks.==8492== suppressed: 0 bytes in 0 blocks.似乎只要子线程被退出(无论是主线程自己退出,还是pthread_cancel,或者是子线程自己走完代码退出)肯定会报内存可能泄露。不过还好,是“可能”,所以还可以接受。
但是下面:
void* thread_test(void* arg){ char* b = new char[88];while(1){printf("sleep\n");sleep(1);}}int main()
{ pthread_t thread1;pthread_create(&thread1,NULL,thread_test,NULL); sleep(3); pthread_cancel(thread1); return 0;}结果是什么呢?==8512== 144 bytes in 1 blocks are possibly lost in loss record 3 of 4==8512== at 0x40046FF: calloc (vg_replace_malloc.c:279)==8512== by 0x4A2E49E9: _dl_allocate_tls (in /lib/ld-2.5.so)==8512== by 0x4A4649D6: (in /lib/libpthread-2.5.so)==8512== by 0x80485A3: main (new2.cpp:15)==8512== ==8512== LEAK SUMMARY:==8512== definitely lost: 0 bytes in 0 blocks.==8512== possibly lost: 144 bytes in 1 blocks.==8512== still reachable: 1,140 bytes in 3 blocks.==8512== suppressed: 0 bytes in 0 blocks.不知道是不是我还不会用的原因,不至于连这么简单的错误也检查不出来吧?有没有高手可以指点一下。