2013-12-13 25 views
0

当一个异常被抛出,然后在那里它被抛出块被从栈unwinded:例外,堆栈展开,包封的堆内存,出口()

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; 
} 

因为良好的教育,我想自己清理垃圾我起来,不能让这样做的OS。我知道,每个现代操作系统本身都会删除一个终止意外(或预期的,但没有明确的重新分配)的程序的堆内存。因此,在上情况下,d的释放会做我的操作系统,但x将仍能正常重新分配内存(因为栈展开和析构函数调用) OS会做到这一点,对不对?

关于什么:

#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

出口不放松像异常抛出一样。但是当你的程序即将死去时,你真的不需要这么做。其他“立即死亡”功能也是如此,例如std :: terminate。 – polkadotcadaver

+0

@polkadotcadaver:当操作系统清理资源时,可能仍然需要销毁对象,例如为了获得缓冲的流清理。然而'exit()'确实不会进行任何本地清理(它仍然会清理全局对象)。 –

+0

@DietmarKühl我同意 - 总是更好地处理优雅清理,特别是在RAII比新/删除更有想象力的情况下使用。 – polkadotcadaver

回答

0

好,我知道感谢polkadotcadaver:从不使用exit(),传播异常,直到main()并在那里做一个简单的return - 所有的堆栈Objects将自己的析构函数被释放之前 OS取得控制权。