0、安装valgrind
wget http://valgrind.org/downloads/valgrind-3.11.0.tar.bz2
tar xvf valgrind-3.11.0.tar.bz2
cd valgrind-3.11.0/
./configure
make
sudo make install
错误:
==24326== Memcheck, a memory error detector
==24326== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==24326== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==24326== Command: ./sample
==24326==
valgrind: Fatal error at startup: a function redirection
valgrind: which is mandatory for this platform-tool combination
valgrind: cannot be set up. Details of the redirection are:
valgrind:
valgrind: A must-be-redirected function
valgrind: whose name matches the pattern: strlen
valgrind: in an object with soname matching: ld-linux-x86-64.so.2
valgrind: was not found whilst processing
valgrind: symbols from the object with soname: ld-linux-x86-64.so.2
valgrind:
valgrind: Possible fixes: (1, short term): install glibc's debuginfo
valgrind: package on this machine. (2, longer term): ask the packagers
valgrind: for your Linux distribution to please in future ship a non-
valgrind: stripped ld.so (or whatever the dynamic linker .so is called)
valgrind: that exports the above-named function using the standard
valgrind: calling conventions for this platform. The package you need
valgrind: to install for fix (1) is called
valgrind:
valgrind: On Debian, Ubuntu: libc6-dbg
valgrind: On SuSE, openSuSE, Fedora, RHEL: glibc-debuginfo
valgrind:
valgrind: Cannot continue -- exiting now. Sorry.
解决办法:
sudo apt-get install libc6-dbg
1、申请的堆内存没有释放 + 对堆内存的访问越界
#include <cstdlib>
void fun() {
int *p = (int *)malloc(10 * sizeof(int));
p[10] = 0;
}
int main() {
fun();
return 0;
}
g++ -g -O0 sample1.cpp -o sample1
valgrind ./sample1
==25248== Memcheck, a memory error detector
==25248== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==25248== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==25248== Command: ./sample1
==25248==
==25248== Invalid write of size 4
==25248== at 0x40054E: fun() (sample.cpp:5)
==25248== by 0x40055E: main (sample.cpp:9)
==25248== Address 0x51fc068 is 0 bytes after a block of size 40 alloc'd
==25248== at 0x4C2AC3D: malloc (vg_replace_malloc.c:299)
==25248== by 0x400541: fun() (sample.cpp:4)
==25248== by 0x40055E: main (sample.cpp:9)
==25248==
==25248==
==25248== HEAP SUMMARY:
==25248== in use at exit: 40 bytes in 1 blocks
==25248== total heap usage: 1 allocs, 0 frees, 40 bytes allocated
==25248==
==25248== LEAK SUMMARY:
==25248== definitely lost: 40 bytes in 1 blocks
==25248== indirectly lost: 0 bytes in 0 blocks
==25248== possibly lost: 0 bytes in 0 blocks
==25248== still reachable: 0 bytes in 0 blocks
==25248== suppressed: 0 bytes in 0 blocks
==25248== Rerun with --leak-check=full to see details of leaked memory
==25248==
==25248== For counts of detected and suppressed errors, rerun with: -v
==25248== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
2、使用未初始化的内存
#include <cstdio>
int main() {
int a[5];
int i, s;
a[0] = a[1] = a[3] = a[4] = 0;
s = 0;
for(i = 0; i < 5; i++)
s += a[i];
if(s == 377)
printf("sum is %d\n", s);
return 0;
}
g++ -g -O0 sample2.cpp -o sample2
valgrind ./sample2
==26180== Memcheck, a memory error detector
==26180== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==26180== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==26180== Command: ./sample2
==26180==
==26180== Conditional jump or move depends on uninitialised value(s)
==26180== at 0x40057B: main (sample2.cpp:10)
==26180==
==26180==
==26180== HEAP SUMMARY:
==26180== in use at exit: 0 bytes in 0 blocks
==26180== total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==26180==
==26180== All heap blocks were freed -- no leaks are possible
==26180==
==26180== For counts of detected and suppressed errors, rerun with: -v
==26180== Use --track-origins=yes to see where uninitialised values come from
==26180== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
3、内存读写越界
#include <cstdio>
#include <cstdlib>
int main() {
int len = 4;
int *pt = (int *)malloc(len * sizeof(int));
int *p = pt;
for(int i = 0; i < len; i++)
p++;
*p = 4;
printf("the value of p equal:%d", *p);
return 0;
}
g++ -g -O0 sample3.cpp -o sample3
valgrind ./sample3
==26686== Memcheck, a memory error detector
==26686== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==26686== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==26686== Command: ./sample3
==26686==
==26686== Invalid write of size 4
==26686== at 0x4005C7: main (sample3.cpp:10)
==26686== Address 0x51fc050 is 0 bytes after a block of size 16 alloc'd
==26686== at 0x4C2AC3D: malloc (vg_replace_malloc.c:299)
==26686== by 0x40059C: main (sample3.cpp:6)
==26686==
==26686== Invalid read of size 4
==26686== at 0x4005D1: main (sample3.cpp:11)
==26686== Address 0x51fc050 is 0 bytes after a block of size 16 alloc'd
==26686== at 0x4C2AC3D: malloc (vg_replace_malloc.c:299)
==26686== by 0x40059C: main (sample3.cpp:6)
==26686==
the value of p equal:4==26686==
==26686== HEAP SUMMARY:
==26686== in use at exit: 16 bytes in 1 blocks
==26686== total heap usage: 1 allocs, 0 frees, 16 bytes allocated
==26686==
==26686== LEAK SUMMARY:
==26686== definitely lost: 16 bytes in 1 blocks
==26686== indirectly lost: 0 bytes in 0 blocks
==26686== possibly lost: 0 bytes in 0 blocks
==26686== still reachable: 0 bytes in 0 blocks
==26686== suppressed: 0 bytes in 0 blocks
==26686== Rerun with --leak-check=full to see details of leaked memory
==26686==
==26686== For counts of detected and suppressed errors, rerun with: -v
==26686== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
4、内存覆盖
#include <cstdio>
#include <cstdlib>
#include <cstring>
int main() {
char x[50];
int i;
for(i = 0; i < 50; i++)
x[i] = i + 1;
strncpy(x + 20, x, 20); //ok
strncpy(x + 20, x, 21); //overlap
strncpy(x, x + 20, 20); //ok
strncpy(x, x + 20, 22); //overlap
x[39] = '\0';
strcpy(x, x + 20); //ok
x[39] = 39;
x[40] = '\0';
strcpy(x, x + 20); //overlap
return 0;
}
g++ -g -O0 sample4.cpp -o sample4
valgrind ./sample4
==27281== Memcheck, a memory error detector
==27281== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==27281== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==27281== Command: ./sample4
==27281==
==27281== Source and destination overlap in strncpy(0xfff000a09, 0xfff0009f5, 21)
==27281== at 0x4C2E333: __strncpy_sse2_unaligned (vg_replace_strmem.c:548)
==27281== by 0x400660: main (sample4.cpp:11)
==27281==
==27281== Source and destination overlap in strncpy(0xfff0009f6, 0xfff000a0a, 22)
==27281== at 0x4C2E333: __strncpy_sse2_unaligned (vg_replace_strmem.c:548)
==27281== by 0x400698: main (sample4.cpp:13)
==27281==
==27281== Source and destination overlap in strcpy(0xfff0009e0, 0xfff0009f4)
==27281== at 0x4C2DD72: strcpy (vg_replace_strmem.c:506)
==27281== by 0x4006D2: main (sample4.cpp:18)
==27281==
==27281==
==27281== HEAP SUMMARY:
==27281== in use at exit: 0 bytes in 0 blocks
==27281== total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==27281==
==27281== All heap blocks were freed -- no leaks are possible
==27281==
==27281== For counts of detected and suppressed errors, rerun with: -v
==27281== ERROR SUMMARY: 3 errors from 3 contexts (suppressed: 0 from 0)
5、动态内存管理错误
#include <cstdio>
#include <cstdlib>
int main() {
int i;
char *p = (char *)malloc(10);
char *pt = p;
for(i = 0; i < 10; i++)
p[i] = 'z';
delete p;
p[1] = 'x';
free(pt);
return 0;
}
g++ -g -O0 sample5.cpp -o sample5
valgrind ./sample5
==30471== Memcheck, a memory error detector
==30471== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==30471== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==30471== Command: ./sample5
==30471==
==30471== Mismatched free() / delete / delete []
==30471== at 0x4C2C171: operator delete(void) (vg_replace_malloc.c:575)
==30471== by 0x4006E9: main (sample5.cpp:10)
==30471== Address 0x5a1c040 is 0 bytes inside a block of size 10 alloc'd
==30471== at 0x4C2AC3D: malloc (vg_replace_malloc.c:299)
==30471== by 0x4006AE: main (sample5.cpp:6)
==30471==
==30471== Invalid write of size 1
==30471== at 0x4006F2: main (sample5.cpp:11)
==30471== Address 0x5a1c041 is 1 bytes inside a block of size 10 free'd
==30471== at 0x4C2C171: operator delete(void) (vg_replace_malloc.c:575)
==30471== by 0x4006E9: main (sample5.cpp:10)
==30471== Block was alloc'd at
==30471== at 0x4C2AC3D: malloc (vg_replace_malloc.c:299)
==30471== by 0x4006AE: main (sample5.cpp:6)
==30471==
==30471== Invalid free() / delete / delete[] / realloc()
==30471== at 0x4C2BD57: free (vg_replace_malloc.c:530)
==30471== by 0x400700: main (sample5.cpp:12)
==30471== Address 0x5a1c040 is 0 bytes inside a block of size 10 free'd
==30471== at 0x4C2C171: operator delete(void*) (vg_replace_malloc.c:575)
==30471== by 0x4006E9: main (sample5.cpp:10)
==30471== Block was alloc'd at
==30471== at 0x4C2AC3D: malloc (vg_replace_malloc.c:299)
==30471== by 0x4006AE: main (sample5.cpp:6)
==30471==
==30471==
==30471== HEAP SUMMARY:
==30471== in use at exit: 0 bytes in 0 blocks
==30471== total heap usage: 1 allocs, 2 frees, 10 bytes allocated
==30471==
==30471== All heap blocks were freed -- no leaks are possible
==30471==
==30471== For counts of detected and suppressed errors, rerun with: -v
==30471== ERROR SUMMARY: 3 errors from 3 contexts (suppressed: 0 from 0)
6、内存泄露
#include <cstdio>
#include <cstdlib>
typedef struct _node {
struct _node *l;
struct _node *r;
char v;
}node;
node *mk(node *l, node *r, char val) {
node *f = (node *)malloc(sizeof(*f));
f->l = l;
f->r = r;
f->v = val;
return f;
}
void nodefr(node *n) {
if(n) {
nodefr(n->l);
nodefr(n->r);
free(n);
}
}
int main() {
node *tree1, *tree2, *tree3;
tree1 = mk(mk(mk(0, 0, '3'), 0, '2'), 0, '1');
tree2 = mk(0, mk(0, mk(0, 0, '6'), '5'), '4');
tree3 = mk(mk(tree1, tree2, '8'), 0, '7');
return 0;
}
g++ -g -O0 sample6.cpp -o sample6
valgrind ./sample6
==31147== Memcheck, a memory error detector
==31147== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==31147== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==31147== Command: ./sample6
==31147==
==31147==
==31147== HEAP SUMMARY:
==31147== in use at exit: 192 bytes in 8 blocks
==31147== total heap usage: 8 allocs, 0 frees, 192 bytes allocated
==31147==
==31147== LEAK SUMMARY:
==31147== definitely lost: 24 bytes in 1 blocks
==31147== indirectly lost: 168 bytes in 7 blocks
==31147== possibly lost: 0 bytes in 0 blocks
==31147== still reachable: 0 bytes in 0 blocks
==31147== suppressed: 0 bytes in 0 blocks
==31147== Rerun with --leak-check=full to see details of leaked memory
==31147==
==31147== For counts of detected and suppressed errors, rerun with: -v
==31147== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)