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字节
如果想学习更多请参考以下具体内容:
首先我给出有问题的源文件用于我们展示如何使用命令:
/*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;
}
gcc -g test.c -o test
其中,-g
选项用于在编译后为程序添加调试信息,以便于开发者进行调试。
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的文件,文件中便是内存信息。
==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个内存泄漏的错误。