
Valgrind

一些最棘手的 C 错误来自内存管理不善:分配错误的大小、使用未初始化的指针、在释放内存后访问内存、溢出缓冲区等,使用valgrind可以帮助我们跟踪这些潜在的错误
Valgrind 内存检查
一、内存错误与内存泄露
Valgrind会报告两种类型的问题
内存错误
- 读取未初始化的内存
- 写入超过一段内存结尾
- 访问释放的内存
内存泄露
- 程序动态分配内存忘记释放
二、在 Valgrind 下运行程序
Valgrind 在你的可执行文件上运行
1 | valgrind ./exec |
带命令函参数
1 | valgrind ./exec argv[1] ... |
三、查找内存错误
常见内存错误
Invalid read/write of size X
读取/写入无效的 X 字节内存。常见原因包括访问超出堆块的末尾、访问已释放的内存或访问未分配的区域
(例如使用未初始化的指针)
Use of uninitialised value
orConditional jump or move depends on uninitialised value(s)
程序读取以前未写入的内存位置的值,即使用随机垃圾
若想追踪未初始化的值,使用
Valgrind --track-origins=yes
Source and destination overlap in memcpy()
试图将数据从一个位置复制到另一个位置,并且要读取的范围与要写入的范围相交
使用
memcpy
可能导致结果混乱,此处应正确使用memmove
Invalid free()
该程序试图多次释放非堆地址或释放同一块
四、查找内存泄露
泄露情况分类
definitely lost
:从未释放的堆分配内存,程序不再拥有指针indirectly lost
:间接丢失,从未释放的堆分配内存,指向它的唯一指针也丢失了,比如链表后面结点的丢失possibly lost
:可能丢失,从未释放的堆分配内存,无法确定是否存在指针still reachable
:仍然可访问,从未释放的堆分配内存,程序退出时仍有指针
鉴于泄漏通常不会导致错误,而不正确的释放会导致错误,我们建议您在程序完成之前不要担心释放内存。
然后,您可以返回并适当地释放您的内存,确保每一步的正确性
如果您需要更多信息,您需要包括选项--leak-check=full
和--show-leak-kinds=all
使用-g
标志进行编译,valgrind
所以能够准确地告诉我们在我们的程序中创建泄漏的位置