Valgrind内存泄漏和内存越界访问检查工具
2016-09-24 12:59
483 查看
在写C/C++程序时,要小心内存泄漏,内存越界访问,但最粗心的也就是这一块;在程序运行过程中,最担心的也就是突然core掉,或程序占用完内存。此时要么DBG产生的core文件,要么是查看日志再对照源代码,假如此时你的源代码修改过。那就是噩梦了。
Valgrind是一个linux平台的内存调试工具。它允许你在Valgrind自己的环境中运行你的程序,监视内存使用,例如:调用malloc和free(或者是C++中的new和delete)。如果使用未初始化的内存,数组访问越界或者忘记释放指针,Valgrind就能够检测出来。
使用valgrind之前 ,当然是要拥有它了。
获得安装包时,使用以下命令解压(下面的xyz是版本号):
此时会创建一个叫valgrind-xyz的目录。切换到该目录,然后执行下列命令:
–prefix指定valgrind的安装目录
使用make和make install时注意当前的权限
现在,valgrind就安装在你的系统里面了。你可以使用以下命令查看:
幸运的是你可以使用valgrind,仅仅运行一下该程序,将会获得一个当前的错误列表。
下面是一个例子example.c。
从上面列出的信息中可以看到在main函数的第4行调用malloc有内存泄漏
下面是示例example2.c
现在使用valgrind
使用valgrind检测之后,会有如下的结果输出:
valgrind甚至智能到足够检测到一个变量初指定一个未初始化的变量,这个变量一直是未初始化的状态,如下代码example4.c所示:
valgrind检测到example4有如下的告警:
声明一个数组:
valgrind不会给你一个告警,一个测试目的地解决方法是修改你的静态数组为在堆上动态分配,这时你会得到内存边界检查,这样会导致一堆未释放的内存。
Valgrind是一个linux平台的内存调试工具。它允许你在Valgrind自己的环境中运行你的程序,监视内存使用,例如:调用malloc和free(或者是C++中的new和delete)。如果使用未初始化的内存,数组访问越界或者忘记释放指针,Valgrind就能够检测出来。
使用valgrind之前 ,当然是要拥有它了。
获得valgrind
如果你的linux系统上还未安装valgrind,你可以用鼠标戳这里穿越到valgrind下载页面。获得安装包时,使用以下命令解压(下面的xyz是版本号):
tar -jxvf valgrind-xyz.tar.bz2 或下面两行命令 bzip2 -d vavlgrind-xyz.bar.bz2 tar -xf valgrind-xyz.tar
此时会创建一个叫valgrind-xyz的目录。切换到该目录,然后执行下列命令:
./configure --prefix=/usr/local/valgrind make make install
–prefix指定valgrind的安装目录
使用make和make install时注意当前的权限
现在,valgrind就安装在你的系统里面了。你可以使用以下命令查看:
which valgrind /usr/local/bin/valgrind 或 valgrind --version valgrind-3.11.0
使用valgrind查看内存泄漏
内存泄漏是所有bugs最难检测到,除非你耗尽所有的内存,否则它不会导致任何显式的错误此,时你调用malloc突然会失败。事实上当使用像C或者C++这类没有垃圾回收机制的语言,几乎一半的时间都浪费在处理正确的释放内存上面。如果你的程序运行的时间足够长,那么查找这个分支上的代码,甚至仅仅一个错误,也会花费很大的代价。幸运的是你可以使用valgrind,仅仅运行一下该程序,将会获得一个当前的错误列表。
下面是一个例子example.c。
#include <stdlib.h> int main() { char *x = malloc(100); /* or,in c++,"char *x=new[100] */ return 0; }
gcc -o example -g example.c % valgrind --tool=memcheck --leak-check=yes example ==9626== 100 bytes in 1 blocks are definitely lost in loss record 1 of 1 ==9626== at 0x4C2911D: malloc (vg_replace_malloc.c:299) ==9626== by 0x40054E: main (example.c:4)
从上面列出的信息中可以看到在main函数的第4行调用malloc有内存泄漏
非法指针使用
valgrind能够发现使用非法的堆内存。使用malloc或者new操作指定一个数组,然后试着去访问数组后面的内存。char x* = malloc(10); x[10] = 'a';
下面是示例example2.c
#include <stdlib.h> int main() { char *x=malloc(10); x[10]='a'; return 0; }
现在使用valgrind
valgrind --tool=memcheck --leak-check=yes exmple2 ==9728== Invalid write of size 1 ==9728== at 0x40055B: main (example2.c:5) ==9728== Address 0x51dd04a is 0 bytes after a block of size 10 alloc'd ==9728== at 0x4C2911D: malloc (vg_replace_malloc.c:299) ==9728== by 0x40054E: main (example2.c:4)
下面来看一下未初始化变量的检测
#include<stdio.h> int main() { int x; if( 0 == x ) { printf("x is zero"); } return 0; }
使用valgrind检测之后,会有如下的结果输出:
==9798== Conditional jump or move depends on uninitialised value(s) ==9798== at 0x400549: main (example3.c:5)
valgrind甚至智能到足够检测到一个变量初指定一个未初始化的变量,这个变量一直是未初始化的状态,如下代码example4.c所示:
#include <stdio.h> int foo(int x) { if( x < 10 ) { printf("x is less than 10\n"); } return 0; } int main() { int y; foo(y); return 0; }
valgrind检测到example4有如下的告警:
==10050== Conditional jump or move depends on uninitialised value(s) ==10050== at 0x40054C: foo (example4.c:4) ==10050== by 0x400570: main (example4.c:14)
什么是valgrind不能发现的?
valgrind不能检测静态数组(在栈上分配的数组)的越界,所发如果在你的代码中声明一个数组:
int main() { char x[10]; x[11] = 'a'; return 0; }
valgrind不会给你一个告警,一个测试目的地解决方法是修改你的静态数组为在堆上动态分配,这时你会得到内存边界检查,这样会导致一堆未释放的内存。
相关文章推荐
- 内存调试——valgrind工具对数组访问错误和内存泄漏的检测
- linux c c++内存检查工具valgrind的使用
- 用Valgrind查找内存泄漏和无效内存访问 zz
- 内存泄漏检查工具valgrind的安装与使用
- 闲着无事,写了一个检测内存越界访问的工具(windows平台)
- 内存检查工具Valgrind介绍
- linux使用valgrind 工具检查内存泄露
- Valgrind ---内存调试,内存泄漏检测以及性能分析的软件开发工具
- 用Valgrind查找内存泄漏和无效内存访问
- 内存检查工具Valgrind
- GFlags 检查内存越界、野指针等作用的工具使用
- Linux下代码内存泄露检查工具valgrind
- 如何使用Valgrind内存检查工具 检查C/C++中内存泄露
- [转]在linux下使用用Valgrind查找内存泄漏和无效内存访问
- linux下内存检查工具valgrind使用方法
- [C++] 内存泄漏检查工具 Valgrind
- linux高级工具命令(四)valgrind做内存检查
- linux 内存泄露,数组越界检测工具valgrind
- 内存泄漏检查工具valgrind使用方法
- Valgrind内存读写越界检测工具使用说明