中易网

如何使用Valgrind内存检查工具 检查C/C++中内存泄露

答案:1  悬赏:60  
解决时间 2021-03-06 23:30
如何使用Valgrind内存检查工具 检查C/C++中内存泄露
最佳答案
使用 Valgrind Memcheck
memcheck工具的使用方式如下:
valgrind --tool=memcheck ./a.out

从上面的命令可以清楚的看到, 主要的命令是valgrind,而我们想使用的工具是通过'-tool'选项来指定的. 上面的‘a.out’指的是我们想使用memcheck运行的可执行文件.
该工具可以检测下列与内存相关的问题 :
未释放内存的使用
对释放后内存的读/写
对已分配内存块尾部的读/写
内存泄露
不匹配的使用malloc/new/new[] 和 free/delete/delete[]
重复释放内存
注意: 上面列出的并不很全面,但却包含了能被该工具检测到的很多普遍的问题.
让我们一个一个地对上面的场景进行讨论:
注意: 下面讨论的所有测试代码都应该使用gcc并且加上-g选项(用来在memcheck的输出中生成行号)进行编译. 就想我们之前讨论过的 C程序被编译成可执行文件, 它需要经历四个不同的阶段.

ToB蓝波湾
翻译于 1 年 前
0人顶
顶 翻译的不错哦!

1. 使用未初始化的内存
Code :
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
char *p;

char c = *p;

printf("\n [%c]\n",c);

return 0;
}

在上面的代码中,我们尝试使用未初始化的指针 ‘p’.
让我们运行Memcheck来看下结果.
$ valgrind --tool=memcheck ./val
==2862== Memcheck, a memory error detector
==2862== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al.
==2862== Using Valgrind-3.6.0.SVN-Debian and LibVEX; rerun with -h for copyright info
==2862== Command: ./val
==2862==
==2862== Use of uninitialised value of size 8
==2862== at 0x400530: main (valgrind.c:8)
==2862==

[#]
==2862==
==2862== HEAP SUMMARY:
==2862== in use at exit: 0 bytes in 0 blocks
==2862== total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==2862==
==2862== All heap blocks were freed -- no leaks are possible
==2862==
==2862== For counts of detected and suppressed errors, rerun with: -v
==2862== Use --track-origins=yes to see where uninitialized values come from
==2862== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 4 from 4)

从上面的输出可以看到,Valgrind检测到了未初始化的变量,然后给出了警告(上面加粗的几行(译者注:貌似上面没有加粗的)).
2. 在内存被释放后进行读/写
Code :
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
char *p = malloc(1);
*p = 'a';

char c = *p;

printf("\n [%c]\n",c);

free(p);
c = *p;
return 0;
}

上面的代码中,我们有一个释放了内存的指针 ‘p’ 然后我们又尝试利用指针获取值.
让我们运行memcheck来看一下Valgrind对这种情况是如何反应的.
$ valgrind --tool=memcheck ./val
==2849== Memcheck, a memory error detector
==2849== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al.
==2849== Using Valgrind-3.6.0.SVN-Debian and LibVEX; rerun with -h for copyright info
==2849== Command: ./val
==2849==

[a]
==2849== Invalid read of size 1
==2849== at 0x400603: main (valgrind.c:30)
==2849== Address 0x51b0040 is 0 bytes inside a block of size 1 free'd
==2849== at 0x4C270BD: free (vg_replace_malloc.c:366)
==2849== by 0x4005FE: main (valgrind.c:29)
==2849==
==2849==
==2849== HEAP SUMMARY:
==2849== in use at exit: 0 bytes in 0 blocks
==2849== total heap usage: 1 allocs, 1 frees, 1 bytes allocated
==2849==
==2849== All heap blocks were freed -- no leaks are possible
==2849==
==2849== For counts of detected and suppressed errors, rerun with: -v
==2849== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 4 from 4)

从上面的输出内容可以看到,Valgrind检测到了无效的读取操作然后输出了警告 ‘Invalid read of size 1′.
另注,使用gdb来调试c程序.
3. 从已分配内存块的尾部进行读/写
Code :
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
char *p = malloc(1);
*p = 'a';

char c = *(p+1);

printf("\n [%c]\n",c);

free(p);
return 0;
}
我要举报
如以上问答内容为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
大家都在看
王者荣耀电脑版键位手势操作怎么设置
好再来拉面店(许昌路店)在哪里啊,我有事要去
化学平衡常数k值的单位,请举例说明
什么是制造业管理者的价值观?
我一哥们被女同学欺负了 是个美女 求报复方法
请教敏感肌用什么干粉粉饼好定妆 补妆 要保湿
如何把UG画的三维图转换为CAD可以用的三维图,
光明小区北门怎么去啊,有知道地址的么
热血传奇还能火吗
10.10.2.1,算24点
一人打虎二人帮,我一个人没有那么大的力量,
ROSE精致女人在什么地方啊,我要过去处理事情
手机qq只能保存最近这几天的聊天记录 怎么解
请老师说说,通达信哪个版本最好用
首义百年的一封信de格式???灰常急急!!!
推荐资讯
中国电信(打古镇百合营业厅)在哪里啊,我有事
郭字左边 反文旁怎么读
嘉信广告在什么地方啊,我要过去处理事情
无聊和寂寞有什么区别?
戏下树地址有知道的么?有点事想过去
和家顺饺子地址有知道的么?有点事想过去
希望ol 甲壳类骨头什么怪掉
excel中,如何提取含有关键词单元的上面第二个
口水三国兔兔子资料
右手手腕粉碎性骨折,医生说好后功能下降,不
罗芳工业区在哪里啊,我有事要去这个地方
冬天到了,书写电热台板可以放键盘和鼠标吗?
手机登qq时,显示手机磁盘不足,清理后重新登
刺客的套装怎么选啊?