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

Exceptions, stack unwinding, encapsulated heap memory, exit()

本文关键字:内存 exit 封装 堆栈 异常      更新时间:2023-10-16

当抛出异常时,抛出异常的块将从堆栈中退出:

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

exit将控制权交还给操作系统之前,x的析构函数是否调用了

更深入:

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
}

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

好的,多亏了polkadotcadaver:永远不要使用exit(),在main()之前传播异常,并在那里做一个简单的return-在操作系统控制之前,所有堆栈Objects都将被自己的析构函数释放。