Когда генерируется исключение, то блок, где он выбрасывается в 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()
, справа?
выход НЕ раскручивается, как исключение. Но поскольку ваша программа вот-вот умрет, как вы ее называете, ей это действительно не нужно. То же самое относится к другим функциям «die now», таким как std :: terminate. – polkadotcadaver
@polkadotcadaver: Несмотря на то, что ресурсы очищены ОС, все же может быть желательно получить объекты, уничтоженные, например, для сброса буферизованных потоков. Однако 'exit()' действительно не выполняет локальную очистку (он все еще очищает глобальные объекты). –
@ DietmarKühl Я согласен - всегда лучше обрабатывать очистку грациозно, особенно там, где RAII используется более изобретательно, чем новый/удалить. – polkadotcadaver