前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C++栈展开如何防止内存泄露

C++栈展开如何防止内存泄露

作者头像
恋喵大鲤鱼
发布2019-02-22 11:30:18
1.1K0
发布2019-02-22 11:30:18
举报
文章被收录于专栏:C/C++基础C/C++基础C/C++基础

在栈展开(stack unwinding)是指,如果在一个函数内部抛出异常,而此异常并未在该函数内部被捕捉,就将导致该函数的运行在抛出异常处结束,所有已经分配在栈上的局部变量都要被释放。如果被释放的变量中有指针,而该指针在此前已经用new运算申请了空间,就有可能导致内存泄露。因为栈展开的时候并不会自动对指针变量执行delete(或delete[])操作。

因此,在有可能发生异常的函数中,可以利用“智能指针”unique_ptr来防止内存泄露。参考如下程序。

#include <iostream>
#include <memory>

using namespace std;

class A 
{
    int num;
public:
    A(int i):num(i)
    {
        cout<<"this is A's constructor, num="<<num<<endl;
    }
    ~A()
    {
        cout<<"this is A's destructor, num="<<num<<endl;
    }
    void show()
    {
        cout<<num<<endl;
    }
};

void uniqueptrtest1()
{
    A* pa=new A(1);
    throw 1;
    delete pa;
}

void uniqueptrtest2()
{
    unique_ptr<A> pa(new A(2));
    pa->show();
    throw 2;
}

int main()
{
    try
    {
        uniqueptrtest1();
    }   
    catch(int)
    {
        cout<<"there is no destructor invoked"<<endl;
    }
    cout<<endl;
    try
    {
        uniqueptrtest2();
    }
    catch(int)
    {
        cout<<"A's destructor does be invoked"<<endl;
    }
}

程序的输出结果:

this is A's constructor, num=1
there is no destructor invoked

this is A's constructor, num=2
2
this is A's destructor, num=2
A's destructor does be invoked

在解读上面的这段程序的时候,要注意以下几点。 (1)在函数uniqueptrtest1()中,由于异常的发生,导致delete pa;无法执行,从而导致内存泄露。 (2)unique_ptr实际上是一个类模板,在名称空间std中定义,要使用该类模板,必须包含头文件memory。unique_ptr的构造函数可以接受任何类型的指针,实际上是利用指针类型将该类模板实例化,并将传入的指针保存在unique_ptr< T>对象中。 (3)在栈展开的过程中,unique_ptr< T>对象会被释放,从而导致unique_ptr< T>对象的析构函数被调用。在该析构函数中,将使用delete运算符将保存在该对象内的指针所指向的动态对象被销毁。这样,就不会发生内存泄露了。 (4)由于已经对*和->操作符进行了重载,所以可以像使用普通的指针变量那样使用unique_ptr< T>对象,如上面程序中的pa->show()。这样可以保留使用指针的编程习惯,方便程序猿编写和维护。


参考文献

[1]陈刚.C++高级进阶教程[M].武汉:武汉大学出版社,2008[P371-P373]

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2015年12月03日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 参考文献
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档