Valgrind工具内存检测

检测维修 0 90

Valgrind安装方法:

按顺序执行以下命令:

从valgrind官网上,下载,名为valgrind - 3.10.0.tar.bz2的压缩包,具体操作为使用wget工具,其链接为http://www.valgrind.org/downloads/valgrind-3.10.0.tar.bz2?

下达指令,将tar,xvf这两个操作应用于valgrind-3.13.0这个对象,以达成解压压缩包此特定目标。

3. cd valgrind-3.10.0

3. 执行 ./configure,参数为 --prefix=/home/UserName/valgrind ,这里需将 UserName 替换成你自己系统的用户名,此操作为配置安装路径。

4. make(从makefile中读取指令,然后编译)

5. 进行make install操作(该操作是从makefile里面读取所设置的指令,然后将相关内容安装到预先指定好的位置)。

配置环境变量时,要进行如下操作,将路径“/home/UserName/valgrind/bin”添加到环境变量“PATH”中。

在安装搞定之后,这一篇章 gonna 针对 valgrind 对于内存的检测情况于五个不同方面予以描述咯:

1. 使用未初始化的内存

有如下程序1:

#include 
using namespace std;
int main()
{
	int a[5];
	int i,s=0;
	a[0]=a[1]=a[3]=a[4]=0;
	for(i=0;i<5;i++)
	  s=s+a[i];
	if(s==33)
	  cout<<"sum is 33"<

程序1里,数组a之中的第二个元素,没有被初始化,然而在for循环当中,仍然去访问数组a的第二个元素,这便是使用未初始化的元素的问题,在运用g++编译器对这个程序进行编译之后再运行,结果如下:

从上面的图能够发觉,程序于编译以及运行的进程当中,并未报出任何的错误,还有异常以及警告。但实际上,程序存有一个巨大的隐患,也就是对未初始化的内存予以访问。我们运用valgrind对这个程序开展检测,结果如下所显示:

从中挑选出1个错误,这个错误是从上图所展示的结果里清晰呈现出来的,其对应的,提示信息是:“Conditional jump or move depends on uninitialised value(s)”,与此同时,错误的位置被提示在源文件test1.cpp里的第10行(额外再交代一下,这里如果要得到具体行数的提示,在我们运用g++进行编译时,需要添加 -g 参数才行)。

2. 内存读写越界

程序2如下所示:

#include 
#include 
using namespace std;
int main()
{
	int len=4;
	int *pt=(int *)malloc(len*sizeof(int));
	int *p=pt;
	for(int i=0;i

在程序2里头,p指针一开始对准了通过malloc获取的4个字节的地址,随后开展了四次自增运算,这意味着p指针自增运算完毕后相较于初始地址偏移了32个字节,而偏移后的地址空间在程序里并未进行申请,于是,p指针变成了野指针,程序里还对p的地址空间实施了写操作,这就导致了内存读写越界的问题,在运用g++编译器对该程序编译并运行时,结果如下:

能够从上面那张图当中发觉,程序于编译以及运行的进程里面并未报出任何的错误、异常还有警告。然而实际上,程序存在越界读写的情况,并且经由malloc获取的地址空间没有被释放,进而造成内存泄漏,这是一个相当大的隐患。我们运用valgrind针对该程序展开检测,结果如下所示:

从上面那幅图的结果里边能够清楚明晰地看到,提示给出了2个错误,提示的信息分别是:“Invalid write of size 4”以及“Invalid read of size 4”,而且提示了错误所在的位置是在源文件test2.cpp里的第11行和第12行。并且检测之后提示了:“1 allocs, 0 frees, 16 bytes allocated”。存在内存泄漏的情况。

3. 内存覆盖

程序3如下所示:

#include 
#include 
#include 
int main()
{
	char x[50];
	int i;
	for(i=0;i<50;i++)
	  x[i]=i+1;
	strncpy(x+20,x,20);
	strncpy(x+20,x,21);
	strncpy(x,x+20,20);
	strncpy(x,x+20,21);
	x[39]='\0';
	strcpy(x,x+20);
	x[39]=39;
	x[40]='\0';
	strcpy(x,x+20);
	return 0;
}

Valgrind安装教程_大内存检测工具_Valgrind内存检测方法

在程序3里面,strncpy(x + 20, x, 21)这条语句,strncpy(x, x + 20, 21)这条语句,strcpy(x, x + 20)这条语句,在开展字符串复制之时,被复制的对要复制的字符串空间存在交集,借助复制操作,会致使初始字符串空间的中的 值被改变,这便是内存覆盖的问题,使用g++编译器去编译并运行该程序,结果如下:

从上面那张图能够发觉,程序于编译以及运行进程当中,并未报出任何差错,异常还有警告。然而实际上存有内存覆盖的状况,当我们没留意,进而再次去运用原始字符串时,已然不是原先那个字符串了。我们运用valgrind对这个程序展开检测,结果如下所示:

能从上面图示的结果里,极为清楚地瞧见到,浮现出3个差错,提示讯息依次是:“Source and destination overlap in strncpy(0xbe9cffd3, 0xbe9cffbf, 21)”,“Source and destination overlap in strncpy(0xbe9cffbf, 0xbe9cffd3, 21)”以及“Source and destination overlap in strcpy(0xbe9cffaa, 0xbe9cffbe)”,而且指出了差错所处位置是在源文件test3.cpp里的第11行,第13行以及第18行。

4. 动态内存管理错误

程序4如下所示:

#include 
#include 
int main()
{
	int i;
	char *p=(char *)malloc(10);
	char *pt=p;
	for(i=0;i<10;i++)
	{
		p[i]='z';
	}
	delete p;
	pt[1]='x';
	free(pt);
	return 0;
}

于程序4里,运用malloc去申请空间,运用delete来释放空间的情况下,二者并不匹配。借助malloc申请了10个字节的空间,却仅仅释放了一个字节的空间。除此之外,针对已释放的空间依旧开展了读写操作。这些属于典型的内存管理错误问题。在运用g++编译器对这个程序进行编译以及运行时,结果如下:

能够从上面那张图里头发觉,程序于运行之际报出了内存方面的错误,然而却并未给出详尽的信息。我们运用valgrind针对这个程序展开检测,结果如下所呈现的那样:

从上图结果中可以清晰的看到,提示出的3个错误。运用malloc去申请空间,运用delete来释放空间,这两者存在不匹配的问题呀:“那种不匹配的free() / delete / delete ”;动用malloc来申请链10个字节大小的空间,仅仅释放链一个字节的空间呀:“ 那种无效的free() / delete / delete / realloc()”;针对释放完的空间还依旧去搞读写这样的操作嘞:“那种大小为1的无效写操作”。

5. 内存泄漏

程序5如下所示:

#ifndef _TREE_
#define _TREE_
typedef struct _node{
	struct _node *l;
	struct _node *r;
	char v;
}node;
node *mk(node *l,node *r,char val);
void nodefr(node *n);
#endif

#include 
#include "tree.h"
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);
	}
}

#include 
#include "tree.h"
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;
}

于程序5里头,借助malloc去申请空间之后,未运用free函数将所申请的内存地址予以释放,进而致使内存泄漏。在运用g++编译器对于该程序实行编译并运行,其结果如下:

能从上面那张图里发觉,程序于编译以及运行进程当中,并未报出任何差错,异常还有警告。然而实际上存有内存泄漏的问题。我们运用valgrind对这个程序展开检测,结果如下所呈现:

如图的结果里,能够清楚明晰地见到,存在着这样的表述,即:“总堆使用情况为:8次分配,0次释放,96字节已分配”。出现提示间接内存泄漏,提示内容为“indirectly lost: 84 bytes in 7 blocks”,出现提示直接内存泄漏,提示内容为“definitely lost: 12 bytes in 1 blocks”,间接内存泄漏所为是指向该内存的指针都位于内存泄漏处,直接泄漏的状况是没有任何指针指向该内存。

此篇之中的代码样例,以及与之相关的内容,均源自于学习徐晓鑫女士所编著的那本《后台开发核心技术与应用实践》而获得,在此特意予以声明。

相关推荐: