现在的位置: 首页 > 自动控制 > 工业·编程 > 正文

C++中避免内存泄漏的几个绝招

2012-11-24 21:00 工业·编程 ⁄ 共 1819字 ⁄ 字号 评论 1 条

    C++程序对内存资源的管理,直接影响到整个程序的性能。内存泄漏可以说是每一个程序员的天敌。然后只要了解C++的特性,养成良好的编程习惯,我们还是可以将这种风险降至最低的。为了使自己编写的程序内存资源管理更加安全可靠,故写此文,总结几个内存资源管理的绝招。

》》》C++学习总结_防止内存泄漏

1. 用类指针(point-like)对象代替原始指针(raw point)

大家都清楚,要对于C#,指针是C++的一种特性。使用指针能给我们带来巨大的方便,但如果使用不旦,内存动态分配以后没有及时收回,那么系统的内存资源极有可能泄漏,直至造成程序崩溃。

例如:

class A {……};             //定义一个类型A

定义好一个对象后,我们一般可以用new方法,来创造一个对象实例。

    A *pA = new A;              //动态分配一个内存,用new方法,相应的就需要调用delete方法,将该内存进行回收.

然而,在大量的程序代码中,直接针对每一个new,使用一个delete的方式,存在以下几个问题

1)  程序进行维护期间,开发人员若不慎增加循环、条件控制流语句,程序在未触及到delete时,就运行了return;

2) 在new和delete之间,由于运行了某些操作,导致出现异常。

因此,我们不能百分百保证,delete语句总是会执行。为了确保内存资源总是能够回收,我们可以将指针,用一个对象来进行操作,从而利用C++的“析构函数自动调用机制”自动释放内存资源。在标准的程序库中,提供了auto_ptr和tr1::shared_ptr两种指针对象,我们也可以称之为智能指针,采用这种指针对象,当对象的生命周期结束时,其析构函数将自动调用delete。其用法如下:

std::auto_ptr<A> pA(new A); 

std::tr1::shared_ptr<A> pA(new A); 

这两个指针对象的区别之处在于:多个auto_ptr不能同时指向同一对象;而多个shared_ptr则可以指向同一对象。正是因为这个不同,造成两者在处理copy构造函数和copy assignment操作符时,也不尽相同。auto_ptr的复行为具有特殊性:

std::auto_ptr<A> pA1(new A); 

std::auto_ptr<A> pA2(pA1);      //pA2指向对象,而pA1为空

pA1 = pA2;                      //pA1指向对象,而pA2为空

2. 成对使用new与delete时应采用相同的形式

一般来讲,new方法可以用于创建单对对象,也可以用于创建数组对象。同样,针对单个对象与数组,调用delete的形式也不尽相同。如下所示的一个例子,就是new与delete调用形式不匹配,从而造成内存没有成功释放。

string* sArray = new string[100]; 

…… 

delete sArray; 

由于sArray是一个数组,因而上述的100个string对象,就必须调用100次析构函数才能完全释放内存,因而正确的做法是:

delete [] sArray; 

因此,如果你在new表达式中使用[ ],必须在相应的delete表达式中也使用[ ]。如果你在new表达式中不使用[ ],那相应的delete表达式也不能使用[ ]。

3. 在独立的语句中构建智能指针

考虑到如下的函数:

void f(std::tr1::shared_ptr<A> pA(new A), fun()); 

编译器在调用f函数的具体内容前,首先要处理被传递的各个实参。上述第一个参由两部分构成:执行new A,然后调用std::tr1::shared_ptr构造函数。所在编译器在调用f之前,必须做三件事:

1. 调用函数fun

2. 执行new A

3. 调用tr1::shared_ptr构造函数

然后,对于C++来讲,编译器的执行顺序是不确定的,如果最终的操作顺序是这样:

1. 执行new A

2. 调用函数fun

3. 调用tr1::shared_ptr构造函数

如果是这样,假如在调用函数fun时,发现了异常,此时new A返回的指针将会遗失,而且没有放入tr1::shared_ptr中,所以就可能在调用这个函数时引发内存泄漏。为了避免这种问题,一般采用两条语句来实现上述代码,如下:

std::tr1::shared_ptr<A> pA(new A); 

f(pA, fun()); 

目前有 1 条留言    访客:0 条, 博主:0 条 ,引用: 1 条

    外部的引用: 1 条

    • 关于VS2008中C/C++内存泄漏的定位的方法 « 求索阁

    给我留言

    留言无头像?