valgrind检测内存泄漏教程

一、 Linux安装Valgrind:

valgrind --version

如果命令输出 Valgrind 的版本信息,说明已经成功安装了 Valgrind。如果命令无法识别 valgrind 命令,那么就说明还没有安装 Valgrind 或者环境变量配置不正确。

没有安装请点击:安装 Valgrind

快捷检测内存泄漏使用方式如下:

root@ubuntu:/mnt/work_space_share/my_programe/C# ls
test.c
root@ubuntu:/mnt/work_space_share/my_programe/C# gcc -g  test.c -o test
root@ubuntu:/mnt/work_space_share/my_programe/C# ls
test  test.c
root@ubuntu:/mnt/work_space_share/my_programe/C# valgrind --tool=memcheck --leak-check=full --show-leak-kinds=all --undef-value-errors=no --log-file=log ./test
test.c main 13 &p = 0x522f040 
test.c main 18 &p = 0x522f4d0 
root@ubuntu:/mnt/work_space_share/my_programe/C# ls
log  test  test.c
root@ubuntu:/mnt/work_space_share/my_programe/C# cat log 
==6995== Memcheck, a memory error detector
==6995== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==6995== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==6995== Command: ./test
==6995== Parent PID: 1528
==6995== 
==6995== 
==6995== HEAP SUMMARY:
==6995==     in use at exit: 10 bytes in 1 blocks
==6995==   total heap usage: 3 allocs, 2 frees, 1,054 bytes allocated
==6995== 
==6995== 10 bytes in 1 blocks are definitely lost in loss record 1 of 1
==6995==    at 0x4C31B0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6995==    by 0x1086F3: main (test.c:11)
==6995== 
==6995== LEAK SUMMARY:
==6995==    definitely lost: 10 bytes in 1 blocks
==6995==    indirectly lost: 0 bytes in 0 blocks
==6995==      possibly lost: 0 bytes in 0 blocks
==6995==    still reachable: 0 bytes in 0 blocks
==6995==         suppressed: 0 bytes in 0 blocks
==6995== 
==6995== For counts of detected and suppressed errors, rerun with: -v
==6995== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
root@ubuntu:/mnt/work_space_share/my_programe/C# 

其中6995 definitely lost: 10 bytes in 1 blocks便是告诉我们内存泄漏10字节
如果想学习更多请参考以下具体内容:

二、 执行命令

首先我给出有问题的源文件用于我们展示如何使用命令:

1.准备测试文件


/*test.c*/

#include 
#include 


int main()
{

	char *p = NULL;

	/*第一次申请空间*/
	p = (char *)malloc(sizeof(char)*10);

	printf("%s %s %d &p = %p \r\n",__FILE__,__func__,__LINE__,p);
	
	/*第二次申请空间*/
	p = (char *)malloc(sizeof(char)*20);

	printf("%s %s %d &p = %p \r\n",__FILE__,__func__,__LINE__,p);

	/*只释放一次*/
	free(p);
	

	return 0;
}

2.编译

gcc -g  test.c -o test

其中,-g 选项用于在编译后为程序添加调试信息,以便于开发者进行调试。

3.找出内存泄漏信息

valgrind --tool=memcheck --leak-check=full --show-leak-kinds=all --undef-value-errors=no --log-file=log ./你的可执行文件名

这个命令是使用 Valgrind 工具对当前目录下的程序进行内存泄漏检查,并输出详细的日志信息。参数选项说明如下:

  • --tool=memcheck:使用 memcheck 工具检测内存错误,包括使用未初始化的变量、读写越界等。
  • --leak-check=full:全面检测内存泄漏,不仅仅检测未释放的内存,还会检测处理时出现的一些问题。
  • --show-leak-kinds=all:显示所有的内存泄漏信息。
  • --undef-value-errors=no:不检查未定义的值错误。
  • --log-file=log:将日志信息输出到 log 文件中。

执行完之后我们便可以看到在文件夹内生成一个名为log的文件,文件中便是内存信息。

4. 分析内存泄漏信息

==6995== Memcheck, a memory error detector
==6995== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==6995== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==6995== Command: ./test
==6995== Parent PID: 1528
==6995== 
==6995== 
==6995== HEAP SUMMARY:
==6995==     in use at exit: 10 bytes in 1 blocks
==6995==   total heap usage: 3 allocs, 2 frees, 1,054 bytes allocated
==6995== 
==6995== 10 bytes in 1 blocks are definitely lost in loss record 1 of 1
==6995==    at 0x4C31B0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6995==    by 0x1086F3: main (test.c:11)
==6995== 
==6995== LEAK SUMMARY:
==6995==    definitely lost: 10 bytes in 1 blocks
==6995==    indirectly lost: 0 bytes in 0 blocks
==6995==      possibly lost: 0 bytes in 0 blocks
==6995==    still reachable: 0 bytes in 0 blocks
==6995==         suppressed: 0 bytes in 0 blocks
==6995== 
==6995== For counts of detected and suppressed errors, rerun with: -v
==6995== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

以上主要显示了在运行名为“test”的程序时存在内存泄漏。具体来说,它显示了 10 字节的内存块在程序退出前未能被释放,并且未保存指向该内存块的指针,因此无法再次释放该内存块。

继续深度分析(感兴趣可以看)

感兴趣的话下面咱们一起逐句分析哈哈 谁让我们那么爱学习呢:

这是一个 Valgrind 的内存检查报告,每一行的作用如下:

==6995== Memcheck, a memory error detector

这句话是 Valgrind 内存检查器的标识。

==6995== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.

这是版权信息,显示了 Valgrind 的作者和版权信息。

==6995== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info

这句话告诉您正在使用哪个版本的 Valgrind 和哪个库(LibVEX)。

==6995== Command: ./test

这句话显示了启动程序的命令。

==6995== Parent PID: 1528

这句话显示了父进程的进程 ID。

==6995== 

这是一个空行,用于分割段落。

==6995== HEAP SUMMARY:

这句话开始了对堆内存的摘要。

==6995==     in use at exit: 10 bytes in 1 blocks

这句话显示在程序退出时还有多少字节的堆内存处于使用状态。

==6995==   total heap usage: 3 allocs, 2 frees, 1,054 bytes allocated

这句话显示了程序总共分配了多少字节的堆内存,包括其中被释放的和未被释放的。

==6995== 

这又是一个空行,用于分割段落。

==6995== 10 bytes in 1 blocks are definitely lost in loss record 1 of 1
==6995==    at 0x4C31B0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6995==    by 0x1086F3: main (test.c:11)

这句话告诉您哪个内存块被泄漏,并提供了分配该内存块的函数和文件。在这个例子中,它显示了在程序的第11行中使用了 malloc 来分配一个内存块,在程序退出时未释放该内存块。

==6995== 

这还是一个空行。

==6995== LEAK SUMMARY:

这句话开始了对泄漏情况的摘要。

==6995==    definitely lost: 10 bytes in 1 blocks

这句话指出了存在明确的内存泄漏,即分配的 10 字节内存块在程序退出时未被释放。

==6995==    indirectly lost: 0 bytes in 0 blocks

这句话指出了间接的内存泄漏,即分配的内存块的指针丢失了,程序无法再次释放该内存块。

==6995==      possibly lost: 0 bytes in 0 blocks

这句话指出可能存在泄漏,但是 Valgrind 无法确定。

==6995==    still reachable: 0 bytes in 0 blocks

这句话显示程序仍然可以访问的内存块的大小,即仍处于程序控制下的内存块。

==6995==         suppressed: 0 bytes in 0 blocks

这句话显示已被抑制的错误和泄漏数量。

==6995== 

又是一个空行。

==6995== For counts of detected and suppressed errors, rerun with: -v

这句话提供有关检测到的错误和被抑制的错误数量的信息。如果需要更详细的信息,请使用 -v 参数再次运行 Valgrind。

==6995== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

这句话告诉您在多少上下文中检测到了多少个错误,在本例中,检测到了1个内存泄漏的错误。

你可能感兴趣的:(夜深人静学Linux,linux)