动态内存管理(二)
内存泄漏&野指针问题:
1、什么是内存泄漏:
内存泄漏指因为疏忽或错误造成程序未能释放已经不再使用的内存的情况。内存泄漏并不是指内存在物理上的消失,而是应用程序分配某段内存后,因为设计错误,失去了对该段内存的控制,因而造成了内存的浪费。
2、泄露分类:
C/C++程序中一般我们关心两种方面的内存泄漏:
堆内存泄漏(Heap leak):
堆内存指的是程序执行中依据须要分配通过malloc / calloc / realloc / new等从堆中分配的一块内存, 用完后必须通过调用相应的 free或者delete 删掉。假设程序的设计错误导致这部分内存没有被释放,那 么以后这部分空间将无法再被使用,就会产生Heap Leak。
系统资源泄漏 :
指程序使用系统分配的资源,比方套接字、文件描述符、管道等没有使用对应的函数释放掉,导致系统 资源的浪费,严重可导致系统效能减少,系统执行不稳定。
3、如何检测内存泄漏:
在linux下内存泄漏检测:
linux下几款内存泄漏检测工具:linux下几款内存泄漏检测工具
在windows下使用第三方工具:VLD工具说明
其他工具:内存泄漏工具比较
4、如何避免内存泄漏:
- 工程前期良好的设计规范,养成良好的编码规范,申请的内存空间记着匹配的去释放。ps:这个理想状 态。但是如果碰上异常时,就算注意释放了,还是可能会出问题。需要下一条智能指针来管理才有保证。
2. 采用RAII思想或者智能指针来管理资源。
3. 有些公司内部规范使用内部实现的私有内存管理库。这套库自带内存泄漏检测的功能选项。
4. 出问题了使用内存泄漏工具检测。ps:不过很多工具都不够靠谱,或者收费昂贵。
打个总结:
解决内存泄露问题主要分为两种:
1. 事前预防型。如智能指针等
2. 事后查错型。如泄漏检测工具
5、杜绝野指针
-
野指针:野指针并不是NULL指针,而是’非法’内存的指针,NULL指针可以用if或这assert来判断,但是这些对野指针并不起作用
-
形成野指针的三个主要原因:
1. 没有初始化指针变量 2. 指针被free()或者delete以后,没有置为NULL,让人误以为还是有效指针 3. 指针操作超越了变量的作用范围 如下方代码案例:
//
char* p = NULL;
char* str = (char*) malloc(100);
//情况1、任何指针定义后都不会进行自动的初始化成NULL指针,默认值会是随机值,无法控制,所以必须要进行初始化
//
class A {
public:
void Func(void)
{ cout<<"A::func()<<endl;"}
void Test(void)
{ //定义外部程序块
A *p = nullptr;
{ //定义内部程序块
A a;
p = &a;// a的生命周期只在此内部程序块中
}
p->Func(); //p此时是野指针
}
}