admin管理员组

文章数量:1532188

与内存有关的问题可以分成两类:内存访问错误和内存使用错误。内存访问错误包括错误地读取内存和错误地写内存。错误地读取内存可能让你的模块返回意想不到的结果,从而导致后续的模块运行异常。错误地写内存可能导致系统崩溃。内存使用方面的错误主要是指申请的内存没有正确释放,从而使程序运行逐渐减慢,直至停止。

首先必须搞懂什么是内存泄漏,其实,业界一直有两种定义:

a. 大众化说法:一块内存由new或者malloc分配了,在程序结束前一直没有被回收。但程序始终有指针指向这块内存。

b. 更严格的说法:一块内存由new或者malloc分配在堆上面,在程序结束前,已经没有任何指针能够指向这块内存了。

对于第一种Memory Leak,其实危害不大,因为一旦进程结束了,所有该进程分配的内存(包括Leak掉的内存)都会被kernel回收。

对于第二种Memory Leak,大家一致认为对大型服务器端运行的程序是有危害的。如果程序一直在执行,Leak的内存会越来越多,可能会耗尽程序的堆内存。

相应的,在Valgrind里面,称第一种Leak“still reachable”,称第二种为“memory leak”。对于memory leak又分为两种。Directly lostIndirectly lost

Memcheck 工具主要检查下面的程序错误:

l   使用未初始化的内存 (Use of uninitialised memory)    

l   使用已经释放了的内存 (Reading/writing memory after it has been free’d)    

l   使用超过 malloc分配的内存空间(Reading/writing off the end of malloc’d blocks)    

l   对堆栈的非法访问 (Reading/writing inappropriate areas on the stack)    

l   申请的空间是否有释放 (Memory leaks – where pointers to malloc’d blocks are lost forever)    

l   malloc/free/new/delete申请和释放内存的匹配(Mismatched use of malloc/new/new [] vs free/delete/delete [])    

l   srcdst的重叠(Overlapping src and dst pointers in memcpy() and related functions)    

 

#include <</span>string.h>

void **rrr;

int main(void)

{

    rrr = malloc(sizeof(void *));

    *rrr = strdup("bbb");

    rrr = NULL;

    return 0;

}

Valgrind检查上面的代码:

$ valgrind --leak-check=full --show-reachable=yes ./a.out

==16420== 4 bytes in 1 blocks are indirectly lost in loss record 1 of 2

==16420== at 0x4A05E1C: malloc (vg_replace_malloc.c:195)

==16420== by 0x374EA79771: strdup (in /lib64/libc-2.5.so)

==16420== by 0x4005E2: main (in /home/zzhan17/test/a.out)

==16420==

==16420== 12 (8 direct, 4 indirect) bytes in 1 blocks are definitely lost in loss record 2 of 2

==16420== at 0x4A05E1C: malloc (vg_replace_malloc.c:195)

==16420== by 0x4005CA: main (in /home/zzhan17/test/a.out)

==16420==

==16420== LEAK SUMMARY:

==16420== definitely lost: 8 bytes in 1 blocks

==16420== indirectly lost: 4 bytes in 1 blocks

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

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

==16420== suppressed: 0 bytes in 0 blocks

如果把上面的“rrr = NULL; ”代码删除, Valgrind不会报告任何memory leak但会显示有memory still reachable,原因是void **rrrglobal pointer,程序退出时rrr还能指向AAABBB

本文标签: valgrind