内存泄漏是指由于疏忽或错误造成程序未能释放已经不再使用的内存,而造成了内存的浪费。
  内存泄漏会因为减少可用内存的数量从而降低计算机的性能。最终,在最糟糕的情况下,过多的可用内存被分配掉导致全部或部分设备停止正常工作,或者应用程序崩溃。
通过以下例子来介绍如何检测内存泄漏问题:

#include <stdlib.h>
#include <iostream>
using namespace std; 
void GetMemory(char *p, int num)
{
    p = (char*)malloc(sizeof(char) * num);//使用new也能够检测出来
} 
int main(int argc,char** argv)
{
    char *str = NULL;
    GetMemory(str, 100);
    cout<<"Memory leak test!"<<endl;
    //开辟了内存但没有释放,如果main中存在while循环调用GetMemory,那么问题将变得很严重
    //while(1){GetMemory(...);}
    return 0;
}


Linux平台下的内存泄漏检测


《1》mtrace :检测一些内存分配和泄漏的失败等.


  mtrace--维基百科


使用方法:程序开始时调用mtace()函数;

  mtace 会将内存情况记录下来存在.log 文件中,存放结果可由环境变量malloc_trace 设定。

    #gcc -o test test.c -g ; 

    #./test ;


   #mtrace ./test malloc.log     会显示多少行出现问题,内存没释放。

#include <stdlib.h>
#include <mcheck.h> 
int main(void) {  
    mtrace(); /* Starts the recording of memory allocations and releases */
    int* a = NULL; 
    a = malloc(sizeof(int)); /* allocate memory and assign it to the pointer */
    if (a == NULL) {
        return 1; /* error */
    } 
    free(a); /* we free the memory we allocated so we don't have leaks */
    muntrace(); 
    return 0;  
}


2.一个非常强大的工具 valgrind

  

memtest支持多核_memtest支持多核


如上图所示知道:

==6118== 100 bytes in 1 blocks are definitely lost in loss record 1 of 1 
 ==6118==    at 0x4024F20: malloc (vg_replace_malloc.c:236) 
 ==6118==    by 0x8048724: GetMemory(char*, int) (in /home/netsky/workspace/a.out) 
 ==6118==    by 0x804874E: main (in /home/netsky/workspace/a.out)

是在main中调用了GetMemory导致的内存泄漏,GetMemory中是调用了malloc导致泄漏了100字节的内存。


3》memwatch: 


1、MEMWATCH 支持ANSI C 

2、它提供结果日志纪录

3、能检测双重释放(double-free)

4、错误释放(erroneous free) 

5、没有释放的内存(unfreed memory)、

6、溢出和下溢等等。

方法:头文件中添加"memwatch.h"; 

    gcc 编译时用gcc -DMEMWATCH -DMW_STDIO -o test -c test.c

日志文件memwatch.log 中包含的信息主要有以下几点:

  测试日期; 

  状态搜集器的信息;

  使用MemWatch 的输出函数或宏(如TRACE 等)的信息。

  MemWatch 捕获的错误信息;

 内存使用的全局信息统计,包括四点:

    1)分配了多少次内存

    2)最大内存使用量

    3)分配内存总量

    4)为释放的内存总数

<3>内存溢出


(2)段错误

访问了错误的内存段,一般是没权限,常见的访问0 地址。

编程中:

1)访问系统数据区,最常见就是给一个指针0 地址。

2)一个指针为NULL,再给里面写数据。

3)内存越界(数组越界,变量类型不一致等)访问到不属于进程的内存区域。


小结:

其实内存泄漏的原因可以概括为:调用了malloc/new等内存申请的操作,但缺少了对应的free/delete,总之就是,malloc/new比free/delete的数量多。我们在编程时需要注意这点,保证每个malloc都有对应的free,每个new都有对应的deleted!!!平时要养成这样一个好的习惯。