(zt)使用Valgrind檢測linux上c++內存泄露

http://wengshanjin.javaeye.com/blog/557940

C++代碼 複製代碼
  1. //mytest.cpp   
  2. int main(int argc, char * argv[])   
  3. //line 120   
  4.  const int N=10;              // # of elements in array   
  5.  const int g_nLargeRange = 500 * 1024 * 1024;   
  6.   
  7.  cout << "Start of tests" << endl;   
  8.  int *p1 = new int(1);      // use to cause leak   
  9.  int *p2 = new int[N];      // allocate an int array   
  10.  int *p3 = new int(2);      // used to test wrong delete   
  11.  char *cp = 0;              // cp is null pointer   
  12.  char ca[3];                // unintialized array   
  13.  char * pLarge = NULL;    // used to test set address range perms: large range   
  14.  cout << "Test 1: off by one" << endl;   
  15.  for (int i=1; i<N+1; i++)  // one-off in loop   
  16.   p2[i] = i;               // err - initialize element p[N]   
  17.  cout << "Test 2: access freed storage" << endl;   
  18.  delete p1;   
  19.  *p1 = 3;                   // err - accessing freed storage   
  20.  cout << "Test 3: using uninitialized storage" << endl;   
  21.  if (p2[0]) cout << "Junk" << endl;// err - used uninit data   
  22.  cout << "Test 4: delete array using scalar delete" << endl;   
  23.  delete p2;                 // err - delete array with scalar delete   
  24.  cout << "Test 5: array delete of scalar" << endl;   
  25.  delete [] p3;              // err - array delete of scalar   
  26.  cout << "Test 6: overlapping storage blocks" << endl;   
  27.  memcpy( ca, &ca[1],2 );    // err - overlapping storage blocks   
  28.  cout << "Test 7: system call using uninitialize data" << endl;   
  29.  sleep( 1 & ca[0] );            // err - uninit data in system call   
  30.  cout << "Test 8: set address range perms: large range" << endl;   
  31.  pLarge = new char[g_nLargeRange];   
  32.  cout << "Test 9: assign to null pointer - seg faults" << endl;   
  33.  *cp = 'a';                 // err - used null pointer (Seg fauilts)   
  34.  cout << "End of tests" << endl;   
  35.  return 0;   
  36. }  
//mytest.cpp
int main(int argc, char * argv[])
{ //line 120
 const int N=10;              // # of elements in array
 const int g_nLargeRange = 500 * 1024 * 1024;

 cout << "Start of tests" << endl;
 int *p1 = new int(1);      // use to cause leak
 int *p2 = new int[N];      // allocate an int array
 int *p3 = new int(2);      // used to test wrong delete
 char *cp = 0;              // cp is null pointer
 char ca[3];                // unintialized array
 char * pLarge = NULL;    // used to test set address range perms: large range
 cout << "Test 1: off by one" << endl;
 for (int i=1; i<N+1; i++)  // one-off in loop
  p2[i] = i;               // err - initialize element p[N]
 cout << "Test 2: access freed storage" << endl;
 delete p1;
 *p1 = 3;                   // err - accessing freed storage
 cout << "Test 3: using uninitialized storage" << endl;
 if (p2[0]) cout << "Junk" << endl;// err - used uninit data
 cout << "Test 4: delete array using scalar delete" << endl;
 delete p2;                 // err - delete array with scalar delete
 cout << "Test 5: array delete of scalar" << endl;
 delete [] p3;              // err - array delete of scalar
 cout << "Test 6: overlapping storage blocks" << endl;
 memcpy( ca, &ca[1],2 );    // err - overlapping storage blocks
 cout << "Test 7: system call using uninitialize data" << endl;
 sleep( 1 & ca[0] );            // err - uninit data in system call
 cout << "Test 8: set address range perms: large range" << endl;
 pLarge = new char[g_nLargeRange];
 cout << "Test 9: assign to null pointer - seg faults" << endl;
 *cp = 'a';                 // err - used null pointer (Seg fauilts)
 cout << "End of tests" << endl;
 return 0;
}


Using the command
valgrind --tool=memcheck --num-callers=50 --leak-check=full  --log-file=memcheck ./mytest

cat memcheck
==29440== Memcheck, a memory error detector.
==29440== Copyright (C) 2002-2007, and GNU GPL'd, by Julian Seward et al.
==29440== Using LibVEX rev 1804, a library for dynamic binary translation.
==29440== Copyright (C) 2004-2007, and GNU GPL'd, by OpenWorks LLP.
==29440== Using valgrind-3.3.0, a dynamic binary instrumentation framework.
==29440== Copyright (C) 2000-2007, and GNU GPL'd, by Julian Seward et al.
==29440== For more details, rerun with: -v
==29440==
==29440== My PID = 29440, parent PID = 21240.  Prog and args are:
==29440==    ./mytest
==29440==
==29440== Invalid write of size 4
==29440==    at 0x804C2DB: main (mytest.cpp:133)
==29440==  Address 0x40f5408 is 0 bytes after a block of size 40 alloc'd
==29440==    at 0x40050B9: operator new[](unsigned) (vg_replace_malloc.c:268)
==29440==    by 0x804C26D: main (mytest.cpp:126)
==29440==
==29440== Invalid write of size 4
==29440==    at 0x804C31C: main (mytest.cpp:136)
==29440==  Address 0x40f53a8 is 0 bytes inside a block of size 4 free'd
==29440==    at 0x400576D: operator delete(void*) (vg_replace_malloc.c:342)
==29440==    by 0x804C315: main (mytest.cpp:135)
==29440==
==29440== Conditional jump or move depends on uninitialised value(s)
==29440==    at 0x804C34E: main (mytest.cpp:138)
==29440==
==29440== Mismatched free() / delete / delete []
==29440==    at 0x400576D: operator delete(void*) (vg_replace_malloc.c:342)
==29440==    by 0x804C3A6: main (mytest.cpp:140)
==29440==  Address 0x40f53e0 is 0 bytes inside a block of size 40 alloc'd
==29440==    at 0x40050B9: operator new[](unsigned) (vg_replace_malloc.c:268)
==29440==    by 0x804C26D: main (mytest.cpp:126)
==29440==
==29440== Mismatched free() / delete / delete []
==29440==    at 0x4005AFD: operator delete[](void*) (vg_replace_malloc.c:364)
==29440==    by 0x804C3E0: main (mytest.cpp:142)
==29440==  Address 0x40f5438 is 0 bytes inside a block of size 4 alloc'd
==29440==    at 0x4004BF9: operator new(unsigned) (vg_replace_malloc.c:224)
==29440==    by 0x804C27D: main (mytest.cpp:127)
==29440==
==29440== Source and destination overlap in memcpy(0xBEEEF860, 0xBEEEF861, 2)
==29440==    at 0x4006949: memcpy (mc_replace_strmem.c:402)
==29440==    by 0x804C41C: main (mytest.cpp:144)
==29440==
==29440== Conditional jump or move depends on uninitialised value(s)
==29440==    at 0xC2A84C: sleep (in /lib/tls/libc-2.3.4.so)
==29440==    by 0x804C455: main (mytest.cpp:146)
==29440==
==29440== Syscall param nanosleep(req) points to uninitialised byte(s)
==29440==    at 0xC2AB60: __nanosleep_nocancel (in /lib/tls/libc-2.3.4.so)
==29440==    by 0x804C455: main (mytest.cpp:146)
==29440==  Address 0xbeeef684 is on thread 1's stack
==29440==
==29440== Conditional jump or move depends on uninitialised value(s)
==29440==    at 0xC2A99C: sleep (in /lib/tls/libc-2.3.4.so)
==29440==    by 0x804C455: main (mytest.cpp:146)
==29440== Warning: set address range perms: large range 524288000 (undefined)
==29440==
==29440== Invalid write of size 1
==29440==    at 0x804C4BB: main (mytest.cpp:150)
==29440==  Address 0x0 is not stack'd, malloc'd or (recently) free'd
==29440==
==29440== Process terminating with default action of signal 11 (SIGSEGV): dumping core
==29440==  Access not within mapped region at address 0x0
==29440==    at 0x804C4BB: main (mytest.cpp:150)
==29440==
==29440== ERROR SUMMARY: 10 errors from 10 contexts (suppressed: 19 from 1)
==29440== malloc/free: in use at exit: 524,288,016 bytes in 2 blocks.
==29440== malloc/free: 11 allocs, 9 frees, 524,288,591 bytes allocated.
==29440== For counts of detected errors, rerun with: -v
==29440== searching for pointers to 2 not-freed blocks.
==29440== checked 149,404 bytes.
==29440==
==29440==
==29440== 16 bytes in 1 blocks are possibly lost in loss record 1 of 2
==29440==    at 0x4004BF9: operator new(unsigned) (vg_replace_malloc.c:224)
==29440==    by 0x260901: std::string::_Rep::_S_create(unsigned, unsigned, std::allocator<char> const&) (in /usr/lib/libstdc++.so.6.0.3)
==29440==    by 0x261049: std::string::_M_mutate(unsigned, unsigned, unsigned) (in /usr/lib/libstdc++.so.6.0.3)
==29440==    by 0x261348: std::string::assign(char const*, unsigned) (in /usr/lib/libstdc++.so.6.0.3)
==29440==    by 0x805BC8C: _GLOBAL__I__ZN3cmx29convertYearMonthDayToLongLongEiiiRy (char_traits.h:258)
==29440==    by 0x805BE1C: (within /home/welkin/svn/cm30/coremail/bin/mytest/mytest)
==29440==    by 0x804A8F4: (within /home/welkin/svn/cm30/coremail/bin/mytest/mytest)
==29440==    by 0x805BD85: __libc_csu_init (in /home/welkin/svn/cm30/coremail/bin/mytest/mytest)
==29440==    by 0xBB4D90: (below main) (in /lib/tls/libc-2.3.4.so)
==29440==
==29440== LEAK SUMMARY:
==29440==    definitely lost: 0 bytes in 0 blocks.
==29440==      possibly lost: 16 bytes in 1 blocks.
==29440==    still reachable: 524,288,000 bytes in 1 blocks.
==29440==         suppressed: 0 bytes in 0 blocks.
==29440== Reachable blocks (those to which a pointer was found) are not shown.
==29440== To see them, rerun with: --leak-check=full --show-reachable=yes
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章