1. 使用未初始化的内存
Code :
01
#include <stdio.h>
02
#include <stdlib.h>
03
04
int
main(
void
)
05
{
06
char
*p;
07
08
char
c = *p;
09
10
printf
(
"\n [%c]\n"
,c);
11
12
return
0;
13
}
在上面的代码中,我们尝试使用未初始化的指针 ‘p’.
让我们运行Memcheck来看下结果.
01
$ valgrind --tool=memcheck ./val
02
==2862== Memcheck, a memory error detector
03
==2862== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al.
04
==2862== Using Valgrind-3.6.0.SVN-Debian and LibVEX; rerun with -h
for
copyright info
05
==2862== Command: ./val
06
==2862==
07
==2862== Use of uninitialised value of size 8
08
==2862== at 0x400530: main (valgrind.c:8)
09
==2862==
10
11
[#]
12
==2862==
13
==2862== HEAP SUMMARY:
14
==2862== in use at
exit
: 0 bytes in 0 blocks
15
==2862== total heap usage: 0 allocs, 0 frees, 0 bytes allocated
16
==2862==
17
==2862== All heap blocks were freed -- no leaks are possible
18
==2862==
19
==2862== For counts of detected and suppressed errors, rerun with: -v
20
==2862== Use --track-origins=yes to see where uninitialized values come from
21
==2862== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 4 from 4)
从上面的输出可以看到,Valgrind检测到了未初始化的变量,然后给出了警告(上面加粗的几行(译者注:貌似上面没有加粗的)).
2. 在内存被释放后进行读/写
Code :
01
#include <stdio.h>
02
#include <stdlib.h>
03
04
int
main(
void
)
05
{
06
char
*p =
malloc
(1);
07
*p =
'a'
;
08
09
char
c = *p;
10
11
printf
(
"\n [%c]\n"
,c);
12
13
free
(p);
14
c = *p;
15
return
0;
16
}
上面的代码中,我们有一个释放了内存的指针 ‘p’ 然后我们又尝试利用指针获取值.
让我们运行memcheck来看一下Valgrind对这种情况是如何反应的.
01
$ valgrind --tool=memcheck ./val
02
==2849== Memcheck, a memory error detector
03
==2849== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al.
04
==2849== Using Valgrind-3.6.0.SVN-Debian and LibVEX; rerun with -h
for
copyright info
05
==2849== Command: ./val
06
==2849==
07
08
[a]
09
==2849== Invalid read of size 1
10
==2849== at 0x400603: main (valgrind.c:30)
11
==2849== Address 0x51b0040 is 0 bytes inside a block of size 1
free
'd
12
==2849== at 0x4C270BD:
free
(vg_replace_malloc.c:366)
13
==2849== by 0x4005FE: main (valgrind.c:29)
14
==2849==
15
==2849==
16
==2849== HEAP SUMMARY:
17
==2849== in use at
exit
: 0 bytes in 0 blocks
18
==2849== total heap usage: 1 allocs, 1 frees, 1 bytes allocated
19
==2849==
20
==2849== All heap blocks were freed -- no leaks are possible
21
==2849==
22
==2849== For counts of detected and suppressed errors, rerun with: -v
23
==2849== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 4 from 4)
从上面的输出内容可以看到,Valgrind检测到了无效的读取操作然后输出了警告 ‘Invalid read of size 1′.
另注,使用gdb来调试c程序.
3. 从已分配内存块的尾部进行读/写
Code :
01
#include <stdio.h>
02
#include <stdlib.h>
03
04
int
main(
void
)
05
{
06
char
*p =
malloc
(1);
07
*p =
'a'
;
08
09
char
c = *(p+1);
10
11
printf
(
"\n [%c]\n"
,c);
12
13
free
(p);
14
return
0;
15
}
在上面的代码中,我们已经为‘p’分配了一个字节的内存,但我们在将值读取到 ‘c’中的时候使用的是地址p+1.
现在我们使用Valgrind运行上面的代码 :
01
$ valgrind --tool=memcheck ./val
02
==2835== Memcheck, a memory error detector
03
==2835== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al.
04
==2835== Using Valgrind-3.6.0.SVN-Debian and LibVEX; rerun with -h
for
copyright info
05
==2835== Command: ./val
06
==2835==
07
==2835== Invalid read of size 1
08
==2835== at 0x4005D9: main (valgrind.c:25)
09
==2835== Address 0x51b0041 is 0 bytes after a block of size 1 alloc'd
10
==2835== at 0x4C274A8:
malloc
(vg_replace_malloc.c:236)
11
==2835== by 0x4005C5: main (valgrind.c:22)
12
==2835==
13
14
[]
15
==2835==
16
==2835== HEAP SUMMARY:
17
==2835== in use at
exit
: 0 bytes in 0 blocks
18
==2835== total heap usage: 1 allocs, 1 frees, 1 bytes allocated
19
==2835==
20
==2835== All heap blocks were freed -- no leaks are possible
21
==2835==
22
==2835== For counts of detected and suppressed errors, rerun with: -v
23
==2835== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 4 from 4)
同样,该工具在这种情况下也检测到了无效的读取操作.
4. 内存泄露
Code:
01
#include <stdio.h>
02
#include <stdlib.h>
03
04
int
main(
void
)
05
{
06
char
*p =
malloc
(1);
07
*p =
'a'
;
08
09
char
c = *p;
10
11
printf
(
"\n [%c]\n"
,c);
12
13
return
0;
14
}
在这次的代码中, 我们申请了一个字节但是没有将它释放.现在让我们运行Valgrind看看会发生什么:
01
$ valgrind --tool=memcheck --leak-check=full ./val
02
==2888== Memcheck, a memory error detector
03
==2888== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al.
04
==2888== Using Valgrind-3.6.0.SVN-Debian and LibVEX; rerun with -h
for
copyright info
05
==2888== Command: ./val
06
==2888==
07
08
[a]
09
==2888==
10
==2888== HEAP SUMMARY:
11
==2888== in use at
exit
: 1 bytes in 1 blocks
12
==2888== total heap usage: 1 allocs, 0 frees, 1 bytes allocated
13
==2888==
14
==2888== 1 bytes in 1 blocks are definitely lost in loss record 1 of 1
15
==2888== at 0x4C274A8:
malloc
(vg_replace_malloc.c:236)
16
==2888== by 0x400575: main (valgrind.c:6)
17
==2888==
18
==2888== LEAK SUMMARY:
19
==2888== definitely lost: 1 bytes in 1 blocks
20
==2888== indirectly lost: 0 bytes in 0 blocks
21
==2888== possibly lost: 0 bytes in 0 blocks
22
==2888== still reachable: 0 bytes in 0 blocks
23
==2888== suppressed: 0 bytes in 0 blocks
24
==2888==
25
==2888== For counts of detected and suppressed errors, rerun with: -v
26
==2888== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 4 from 4)
输出行(上面加粗的部分)显示,该工具能够检测到内存的泄露.
注意: 在这里我们增加了一个选项‘–leak-check=full’来得到内存泄露的详细细节.