2013-12-13 2 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; 
} 

Из-за хорошего образования, я хочу, чтобы очистить свой мусор до сам, и не позволять делать это ОС. Я знаю, что каждая современная ОС сама по себе удаляет кучу памяти программы, которая заканчивается неожиданным (или ожидаемым, но без явного освобождения). Таким образом, в верхнем регистре освобождение 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

выход НЕ раскручивается, как исключение. Но поскольку ваша программа вот-вот умрет, как вы ее называете, ей это действительно не нужно. То же самое относится к другим функциям «die now», таким как std :: terminate. – polkadotcadaver

+0

@polkadotcadaver: Несмотря на то, что ресурсы очищены ОС, все же может быть желательно получить объекты, уничтоженные, например, для сброса буферизованных потоков. Однако 'exit()' действительно не выполняет локальную очистку (он все еще очищает глобальные объекты). –

+0

@ DietmarKühl Я согласен - всегда лучше обрабатывать очистку грациозно, особенно там, где RAII используется более изобретательно, чем новый/удалить. – polkadotcadaver

ответ

0

Хорошо, получил его благодаря polkadotcadaver: никогда не использовать exit(), не распространяются исключения до main() и сделать там простой return - все стек Objects будут освобождаться от их собственного деструктора до того OS берет под свой контроль.

Смежные вопросы