异常,堆栈展开,封装堆内存,exit()

时间:2013-12-13 22:15:25

标签: c++ exception heap exit stack-unwinding

当抛出异常时,抛出它的块从堆栈中取消:

int main ()
{
    try
    {
        Object x; // doesn't throw
        Object y; // throws
        cout << "wonderful";
    }
    catch (...)
    {
        cout << "fail";
    }
}

Object在堆上的构造内存上分配并在销毁时正确释放它时,应该没有内存泄漏,因为堆栈展开会调用x的析构函数(不是y的析构函数,但Object保证,当构造函数失败时,则没有内存泄漏)。好吧,不是吗?

让我们深入探讨:

int main ()
{
    Object x; // doesn't throw
    double *d = new double[256*256*256]; // doesn't throw
    Object y; // throws
    cout << "wonderful";
    delete[] d;
}

由于良好的教育,我想自己清理垃圾,而不是让操作系统。我知道,每个现代操作系统都会自行删除程序的堆内存,这会终止意外(或预期,但没有明确的释放)。所以在大写的情况下,d的释放将执行我的操作系统,但是x仍然可以在操作系统之前正确释放其内存(因为堆栈展开和析构函数调用)会做的,对吗?

那是怎么回事:

#include <cstdlib>

int main ()
{
    Object x; // doesn't throw
    try { Object y; } // throws
    catch (...) {  cout << "fail"; exit(EXIT_FAILURE); }
    cout << "working and working...";
    cin.get();
}

x之前被称为exit的析构函数是否将控制权交还给操作系统?

更深入:

void Object::be_stupid ()
{
    Object a; // doesn't throw
    try { Object b; }// throws
    catch (...) { exit(EXIT_FAILURE); }
}

void main ()
{
    Object x; // doesn't throw
    try { x.be_stupid(); } // exits program
}

x之前调用exit的构造函数是否将控制权交还给操作系统?如果是,那么exit“展开”所有周围的堆栈,包括main(),对吗?

1 个答案:

答案 0 :(得分:0)

好的,感谢polkadotcadaver:永远不要使用exit(),将异常传播到main()并做一个简单的return - 所有堆栈Objects将被他们取消分配操作系统控制之前自己的析构函数