1 Valgrind及组件memcheck简要介绍
Valgrind是一套Linux下的仿真调试工具的集合,有内核core以及基于内存的其他调试工具组成,主要用于检查程序中的内存错误、内存泄漏和并发问题。它提供了一系列的工具,包括Memcheck、Cachegrind、Callgrind、Helgrind等,每个工具都有不同的功能和用途。
memcheck是Valgrind最常用的工具之一,用于检测内存错误和泄漏。它通过在运行程序时对内存进行动态分析,检测未初始化的变量、使用已释放内存、访问越界以及内存泄漏等问题。memcheck还可以跟踪内存的分配和释放操作,帮助定位问题代码的位置,并提供详细的错误报告和堆栈跟踪信息。
2 安装
在Ubuntu下进入终端,使用apt进行安装。
$ sudo apt install valgrind
3 memcheck使用
常见的内存问题一共5种:
1.使用野指针,即未初始化的指针;
2.释放野指针,即未初始化的指针;
3. 动态内存越界;
4. 堆内存泄漏,没有成对和不匹配使用malloc/free和new/delete;
5.两次释放内存;
使用memcheck调试工具前,在利用g++
对.cpp
程序进行编译时需要加上选项-g
。进行内存泄漏检测时使用命令$ valgrind --tool = memcheck [可执行文件]
。
$ g++ condition01.cpp -o c01 -g
$ valgrind --tool=memcheck ./c01
2.1 使用未初始化的内存(使用野指针)
代码:
g++编译及运行结果:
程序正常运行,返回的一个随机值。
memcheck结果:
可以看出,报错使用了未初始化的值(Use of uninitialised value),定位到12
行代码。
2.2 内存释放后进行读/写(释放野指针)
代码:
g++编译及运行结果:
程序正常运行,返回a的值100。
memcheck结果:
可以看出, 报错无效读取数值(Invalid read),定位到第18
行代码。
2.3 已分配的内存块的尾部进行读/写(动态内存越界)
代码:
g++编译及运行结果:
程序正常运行。
memcheck结果:
可以看出,报错内存越界访问,定位到第11
行代码;堆内存检测报错内存泄漏,用了1次allocs,0次frees。
2.4 内存泄漏(没有成对使用malloc/free和new/delete)
代码:
g++编译及运行结果:
程序正常运行。
memcheck结果:
可以看出,报错堆内存中内存泄漏,用了1次allocs,0次free。
使用--leak-check=full
命令可以进一步获取内存泄漏的信息,比如malloc和free具体行号。
$ valgrind --tool=memcheck --leak-check=full ./c04
可以看出,malloc发生在第9
行,但没有对应的free释放内存。
2.5 不匹配的使用malloc/new/new[] 和 free/delete/delete[]
2.5.1 正确使用
代码:
g++编译及运行结果:
程序正常运行。
memcheck结果:
显示一切正常。
2.5.2 错误匹配使用
代码:
g++编译及运行结果:
程序正常运行。
memcheck结果:
可以看出,提示不匹配(Mismatched free() / delete / delete []),定位第18
行代码。
2.6 两次释放内存
代码:
g++编译及运行结果:
报错! 检测到重复free。
memcheck结果:
可以看出,报错无效的释放内存,并显示进行了2次free(Invalid free() / delete / delete[] / realloc() ), 在HEAP SUMMARY
中提示1次allocs,2次frees。
附件
示例程序链接:https://download.csdn.net/download/weixin_43780617/88062996?spm=1001.2014.3001.5503
打包好了的.cpp文件和可执行文件
References
- https://zhuanlan.zhihu.com/p/75328270
- https://zhuanlan.zhihu.com/p/493972853