利用destructors 避免泄漏资源

Posted vector6_

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了利用destructors 避免泄漏资源相关的知识,希望对你有一定的参考价值。

利用destructors 避免泄漏资源

某些场景下,我们需要用指针来操控局部性资源,例如:

class dataHeader;
void process(istream& data)

	while(data)
	
		dataHeader* = readData(data);
		dataHeader->processHeader();
		delete dataHeader;
	

就如上面的代码段,在 process() 函数中,读取data 的header 并且处理消息头,需要特别谨慎的是,它必须在每次迭代处理的最后,记得将dataHeader 删除,以防止出现资源泄漏。

但是我们现在要考虑如果dataHead->processHeader() 发生异常,且没有捕获它,那么process()函数内所有位于dataHead->processHeader() 之后的所有语句都会被跳过,这时dataHeader就不会被delete。会发生资源泄漏。

要避免这种危险,一个方法是:

class dataHeader;
void process(istream& data)

	while(data)
	
		dataHeader* = readData(data);
        try
			dataHeader->processHeader();            
        
		catch(...)						//捕获所有exceptions
            delete dataHeader;
            throw;
        
		delete dataHeader;				//如果没有exceptinos 被抛出,也要避免资源泄漏
	

但是这样使用try-catch其实是有些麻烦的,因为不论我们是以正常方式还是异常方式离开processHeaader函数,都是需要delete dataHeader。如果可以集中在一处做这件事会更好。

将清理资源代码转移到destructor中

我们应该考虑将一定得执行的清理代码转移到某个局部对象的destructor中,因为局部对象不论如何结束的 ,总是会在函数结束时被析构。

更具体的方法是:使用一个类似指针的对象来代替指针dataHeader,这样的话,在这个对象被销毁是,我们可以令其destructor 调用 delelte。这种思想的一个实现就是智能指针 shard_ptr/unique_ptr 。智能指针实际上是个类模板,对象构造时会要求获得一个指向堆对象的指针,而析构时会将该指针及内存释放。

我们将这个思想推广,其实隐藏在智能背后的观念是:以一个对象存放“必须自动释放的资源”,并依赖该对象的destrutor来释放资源。这种思想也可以对指针以外的资源如文件描述符等使用。即将Handle、description 等放在类内,并借由destructor 来释放这些资源。

以上是关于利用destructors 避免泄漏资源的主要内容,如果未能解决你的问题,请参考以下文章

智能指针

Java 标准 API 中的内存泄漏陷阱

在Java程序中这样会不会造成内存泄漏?

如何处理 terraform 进程崩溃并避免重试时资源泄漏?

避免、发现和消除 Cocoa 中的内存泄漏

RAII