01。前言C/C++运行高效。无论是操作系统内核还是有性能要求的程序(比如游戏引擎),都需要使用C/C++来编写。其实C/C++强大的一点就在于可以自由使用指针,及时控制内存的使用,及时申请内存,及时释放内存,从而达到其他编程语言无法高效运行无法实现。但是内存管理是一把双刃剑。用得好,削铁如泥,用得不好,断臂。应用堆上的内存用完后,如果不能及时有效地释放,就会造成内存泄漏,久而久之,程序就会耗尽系统内存,导致系统出现问题。这就像你每天去图书馆借十几本书,直到图书馆关门才归还。C语言申请内存和释放内存的方法是使用malloc和free。C++兼容C,所以也可以使用malloc和free,面向对象的情况下使用new和delete,可以自动执行构造函数和析构函数。在Linux平台上,我们可以使用valgrind命令来检测C/C++程序是否存在内存泄漏。02.在debian/ubuntu上安装valgrind安装方法:deng@itcast:~$sudoaptinstallvalgrinddeng@itcast:~$sudoyuminstallvalgrind安装好valgrind工具后,我们来看看valgrind的几个应用场景。redhat/centos下的安装方法:03.使用未初始化的内存在程序中,我们定义了一个指针p,但是没有给他分配空间,但是我们使用了它。程序示例:#include#include#includeintmain(void){charch;字符*p;ch=*p;printf("ch=%cn",ch);返回0;}valgrind检测到我们的程序使用了未初始化的变量。04.野指针p指向的内存被释放,p变成了野指针,但是我们继续使用这块内存。程序示例:#include#include#includeintmain(void){int*p=NULL;p=malloc(sizeof(int));if(NULL==p){printf("malloc失败...n");返回1;}memset(p,0,sizeof(int));*p=88;printf("*p=%dn",*p);//释放内存free(p);printf("*p=%dn",*p);返回0;}valgrind检测到我们已经使用了空闲内存,并给出了该内存的分配位置和释放位置。05.动态内存越界访问我们动态分配了一个连续的存储空间,但是在访问一个数组的时候发生了越界访问。程序示例:#include#include#includeintmain(void){inti=0;int*p=NULL;p=malloc(5*sizeof(int));if(NULL==p){printf("mallocfailed...n");return1;}memset(p,0,10*sizeof(int));for(inti=0;i<=5;i++){p[i]=i+1;}for(inti=0;i<=5;i++){printf("p[%d]:%dn",i,p[i]);}返回0;}Valgrind检测越界信息如下。注意:valgrind不检查非动态分配数组的使用情况。06.分配空间后内存泄漏没有释放的原因是我们使用free或new分配空间后,没有使用free或delete释放内存。程序示例:#include#include#includeintmain(void){int*p=NULL;p=malloc(sizeof(int));*p=88;printf("*p=%dn",*p);返回0;}Valgrind的记录显示,上面的程序使用了一次malloc,但是调用了0次free。您可以使用--leak-check=full来获取有关内存泄漏的更多信息,例如malloc的具体行号。07.不匹配使用delete或free一般我们使用malloc分配的空间,必须使用free来释放内存。使用new分配空间,使用delete释放内存。程序示例:#include#include#includeintmain(void){int*p=NULL;p=(int*)malloc(sizeof(int));*p=88;printf("*p=%dn",*p);删除p;返回0;malloc/new/new[]和free/delete/delete[]的不匹配使用会提示mismacth08。两次释放同一块内存。一般情况下,内存分配一次,释放一次。如果多次释放,可能会发生双重释放。程序示例:#include#include#includeintmain(void){int*p=NULL;p=(int*)malloc(sizeof(int));*p=88;printf("*p=%dn",*p);免费p;免费p;返回0;}多次释放同一内存,非法释放内存。09.小结内存泄漏的问题是很难定位的。对于小型工程项目,只要检查代码中new和delete的匹配对数就可以基本定位到问题所在。检查定位问题是非常困难的,所以我们需要借助工具来帮助我们发现问题。Valgrind,一个非常好用的开源内存管理工具,是Linux下第一款内存检测工具。Valgrind其实是一个工具集,内存错误检测只是它的众多功能之一,不过我们用的最多的功能还是它——memcheck。推荐了解一下传智播客的C++培训课程。总之,valgrind工具可以检测以下与内存相关的问题:使用未释放的内存读/写释放的内存读/写分配内存块的尾部内存泄漏malloc/new/new[]和free/delete的不匹配使用/delete[]反复释放内存