参考:blog.csdn.net/kangroger/article/details/39317503
www.cnblogs.com/Sharley/p/5285045.html
内存溢出:指程序在申请内存时,没有足够多的内存空间供其使用,出现out of memory
内存泄漏:指程序申请内存后,无法释放已申请的内存空间
C++中的内存泄漏一般指堆中的内存泄漏
内存泄漏分为4类:
1.常发性内存泄漏:发生内存泄漏的代码会被多次执行到,每次被执行的时候都会导致一块内存泄漏。
2.偶发性内存泄漏:发生内存泄漏的代码只有在某些特定环境或操作过程下才会发生。常发性和偶发性是相对的。对于特定的化境,偶发性也许就变成了常发性
3.一次性内存泄漏:发生内存泄漏的代码只会被执行一次,或者由于算法上的缺陷,导致总会有一块且仅有一块内存发生泄漏。比如,在类的构造函数中分配内存,在析构函数中没有释放该内存,所以内存泄漏只会发生一次。
4.隐式性内存泄漏:程序在运行过程中不停的分配内存,直到结束的时候才释放内存。严格的说这里没有发生内存泄漏,因为最终程序会释放内存,但是对于一个服务器程序,需要运行几天,几周甚至几个月,不及时释放内也可能导致最终耗尽系统的所有内存。
内存泄漏的原因:
1.内存中加载的数据量过于庞大
2.编码错误:malloc,realloc,new申请的内存在堆上,需要手动释放,调用free/delete,申请和释放必须同时出现,malloc/realloc(不会运行构造/析构函数)对应free,new对应delete。
3.无主内存:申请内存后,指针指向内存的起始地址,若丢失或修改这个指针,那么神奇的内存将丢失并且没有释放。
4.异常分支导致资源未释放:程序正常执行没有问题,但是如果遇到异常,正常执行的顺序或分支会被打断,得不到执行。在异常处理代码中,要确保系统资源的释放。
5.类的析构函数和非析构函数:析构函数为虚函数,利用多态来带哦用指针指向对象的析构函数,而不是基类的析构函数。
内存泄漏的检测:
内存泄漏的关键就是记录分配的内存和释放内存的操作,看看能不能匹配。
windows下检测内存泄漏的方法:
vs调试器和C运行时(CRT)库为我们提供了检测和识别内存泄漏的有效方法,原理大致为:内存分配要通过CRT在运行时实现,只要在分配内存和释放内存时分别做好记录,程序结束时对比分配内存和释放内存的记录就可以确定是不是有内存泄漏。在vs中启用内存检测方法如下:
step1在程序中包括以下语句:
#define _CRTDBG_MAP_ALLOC
#include<stdlib.h>
#include<crtdbg.h>
通过报刊crtdbg.h将malloc和free函数映射到它们的调试版本,即_malloc_dbg和_free_dbg,这两个函数将跟踪内存分配和释放。此映射只在调试版本中发生,发布版本使用普通的malloc和free函数。
step2,通过以下语句来转储内存泄漏信息:
_CrtDumpMemoryLeaks();
Linux平台下的内存泄漏检测
Linux有和vs类似的方法——mtrace
mtrace是一个C函数,在<mcheck.h>里声明及定义,函数原型为:
void mtrace(void);