Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/64.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 异常、堆栈展开、封装的堆内存、退出()_C++_Exception_Heap_Exit_Stack Unwinding - Fatal编程技术网

C++ 异常、堆栈展开、封装的堆内存、退出()

C++ 异常、堆栈展开、封装的堆内存、退出(),c++,exception,heap,exit,stack-unwinding,C++,Exception,Heap,Exit,Stack Unwinding,当抛出异常时,抛出异常的块将从堆栈中取消: int main () { try { Object x; // doesn't throw Object y; // throws cout << "wonderful"; } catch (...) { cout << "fail"; } } 由于良好的教育,我想自己清理垃圾,而不是让操作系统来做。我知道,每个现

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

int main ()
{
    try
    {
        Object x; // doesn't throw
        Object y; // throws
        cout << "wonderful";
    }
    catch (...)
    {
        cout << "fail";
    }
}
由于良好的教育,我想自己清理垃圾,而不是让操作系统来做。我知道,每个现代操作系统都会自行删除程序的堆内存,该程序会意外或预期终止,但不会显式释放。所以在上面的例子中,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将控制权交还给OS之前是否调用了x的构造函数?如果是,那么exit将展开包括main在内的所有周围堆栈,对吗?

好的,多亏了polkadtcadaver:永远不要使用exit,在main之前传播异常,并在那里执行一个简单的返回-在操作系统控制之前,所有堆栈对象都将由它们自己的析构函数解除分配。

exit不像异常抛出那样展开。但是,正如你所说,你的程序即将消亡,它真的不需要。其他die now函数(如std::terminate)也是如此。@polkadtcadaver:虽然操作系统清理了资源,但仍然需要销毁对象,例如刷新缓冲流。然而,exit确实不会进行任何本地清理,它仍然会清理全局对象。@DietmarKühl我同意-优雅地处理清理总是更好的,尤其是在RAII比new/delete更具想象力的地方。您可以查看。它详细解释了抛出如何导致内存泄漏。@mb84将main声明为int main,而不是exit just return,然后所有内容都将像离开任何函数时一样被清除,程序也将退出并清除静态对象。
#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();
}
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
}