欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

内存泄漏

程序员文章站 2022-04-19 15:33:18
...

内存泄漏 

1. 内存泄漏:内存泄漏指因为疏忽或错误造成程序未能释放已经不再使用的内存的情况,内存泄漏并不是指内存在物理上的消  失,  而是应用程序分配某段内存后,因为设计错误,失去了对该段内存的控制,因而 造成了内存的浪费。 

程序中通常包含着静态内存和栈内存。静态内存用来保存局部static对象、类static数据成员以及定义在任何函数之外的变量(全局变量)。栈内存用来保存定义在函数内的非static对象。分配在静态或栈内存中的对象由编译器自动创建和销毁。对于栈对象,仅在定义的程序块运行时才存在,程序退出,栈对象也随即销毁;static对象和全局对象则是在程序结束时销毁。除了静态内存和栈内存,程序还拥有一块内存池,这部分也就是称为堆。在使用堆空间是就需要使用动态内存分配。

     内存泄漏的危害:长期运行的程序出现内存泄漏,影响很大,如操作系统、后台服务等等,出现内存泄漏会导致响应越来越慢,最终卡死。

void MemoryLeaks()
{
	//内存申请了忘了释放
	int* p1 = (int*)malloc(sizeof(int));
	int* p2 = new int;

	//异常安全问题
	int* p3 = new int[10];


	Func(); //这里Func函数抛异常导致delete[] p3未执行,p3没被释放.

	delete[] p3;
}

2. 内存泄漏分类 

1)堆内存泄漏(Heap leak)

堆内存指的是程序执行中依据须要分配通过malloc / calloc / realloc / new等从堆中分配的一块内存, 用完后必须通过调用相应的 free或者delete 删掉。假设程序的设计错误导致这部分内存没有被释放,那 么以后这部分空间将无法再被使用,就会产生Heap Leak。

2)系统资源泄漏

指程序使用系统分配的资源,比方套接字、文件描述符、管道等没有使用对应的函数释放掉,导致系统 资源的浪费,严重可导致系统效能减少,系统执行不稳定。

3.如何避免内存泄漏

 1. 工程前期良好的设计规范,养成良好的编码规范,申请的内存空间记着匹配的去释放。ps:这个理想状 态。但是如果碰上异常时,就算注意释放了,还是可能会出问题。需要下一条智能指针来管理才有保 证。

1)      正确的使用new和delete运算符,需要注意的是new和delete要匹配使用,防止在指针p的值被另一个函数所使用。

char * FunA()
{
	char *p = new char;
	return p;
}
void FunErrorB()
	{
		char *b = FunA();
		//忘记delete p	
	}

2)      释放对象数组时,没有使用delete[]。

Void FunErrorA()
{
	Char *p = new char[10];
	Delete p;
}

3)双指针释放错误,防止指针释放的遗漏

Void FunRightA()
		{
			Char **p = new char*[10];
			For(int i = 0; i<10; i++)
			{
				p[i] = new char[10];
			}
			If(p != nullptr)
			{
				For(int i = 0; i<10; i++)
				{
					Delete[]p[i];
					p[i] = nullptr;
				}
				Delete[]p;
				p = nullptr;
			}

2. 采用RAII思想或者智能指针来管理资源。

3. 有些公司内部规范使用内部实现的私有内存管理库。这套库自带内存泄漏检测的功能选项。

4. 出问题了使用内存泄漏工具检测。ps:不过很多工具都不够靠谱,或者收费昂贵。

总结一下: 内存泄漏非常常见,解决方案分为两种:1、事前预防型。如智能指针等。2、事后查错型。如泄漏检测工 具。