memcheck是valgrind的默认使用工具;
$ valgrind --leak-check=yes myprog arg1 arg2
void foo()
{
int *buf;
buf = alloc(10, sizeof(int));
buf[10] = 10; // 访问非法内存
// 没有释放内存,导致内存泄露
}
int main()
{
foo();
return 0;
}
valgrind的输出内容为:
==19182== Invalid write of size 4
==19182== at 0x804838F: f (example.c:6)
==19182== by 0x80483AB: main (example.c:11)
==19182== Address 0x1BA45050 is 0 bytes after a block of size 40 alloc'd
==19182== at 0x1B8FF5CD: malloc (vg_replace_malloc.c:130)
==19182== by 0x8048385: f (example.c:5)
==19182== by 0x80483AB: main (example.c:11)
19182是进程id; Invalid write表示错误类型,然后是错误发生的位置,整个的backtraces流程;
建议按顺序修改错误。
有两种类型的内存泄露:绝对泄露和可能泄露;memcheck同时也检查未初始化变量。
memcheck检测的错误范围:
- 非法读/写错误
- 使用未初始化变量
- 系统调用中参数未初始化或未指明地址
- 非法释放
- 在不合适的释放函数中释放内存块
- 覆盖源/目的地址块
- 内存泄露
- Fishy 参数值 (内存分配的函数的size参数)
内存分配和释放函数不匹配:
使用malloc
, calloc
, realloc
, valloc或
memalign分配的内存,使用free函数进行释放。
使用new分配函数与delete匹配;
new[]函数与delete[]配对;
拷贝数据 memcpy
, strcpy
, strncpy
, strcat
, strncat函数
valgrind之memcheck命令行参数:
--leak-check=<no|summary|yes|full> ,默认值为summary
--show-leak-kinds=<set>, set以逗号分隔,可能的值:none/all/(definite, indirect, possible, reachable)
--errors-for-leak-kinds=<set> [default: definite,possible]
--undef-value-errors=<yes|no> [default: yes] 未定义值错误