Is it possible to terminate software execution without skipping calls to destructors? For instance, in the code below, the destructor for test
will never be called because of the exit(1)
statement.
#include <iostream>
#include <cstdlib>
using namespace std;
class A{
public:
A(){cout << "Constructed.\n";}
~A(){cout << "Destroyed.\n";}
};
void func()
{
//Assuming something went wrong:
exit(1);
}
int main(int argc, char *argv[])
{
A test;
func();
return 0;
}
What I need, is a way to end the program (from within func()
) that calls all necessary destructors before terminating. So far I've been handling this through func()
return value, as in:
bool func()
{
//Assuming something went wrong:
return false;
}
int main(int argc, char *argv[])
{
A test;
if( !func() )return 1;
return 0;
}
The problem with this method is that it quickly becomes very annoying (and code bloating) to manage once you need to apply it to a series of nested functions.
Is there a way of achieving the same results of the second example (proper destructor calls) with a syntax similar to the first example (call exit(1)
wherever you are)?
When exit(0) is used to exit from program, destructors for locally scoped non-static objects are not called. But destructors are called if return 0 is used.
Because you have a memory leak.
We know that if a destructor is not provided, the compiler will generate one. This means that anything beyond simple cleanup, such as primitive types, will require a destructor. In many cases, dynamic allocation or resource acquisition during construction, has a clean up phase.
If you run this program and press control-C, you should see the word "destructor" printed.
Throw an exception, catch it in main
and return.
This relies on nothing else catching your exception without rethrowing it.
You could rely on stack unwinding for this: when you want to exit, throw an exception and catch it in main()
.
struct my_exit
{
int error;
int operator()()
{
// do any cleanup on globals
return error;
}
};
int main()
{
try
{
doSomethingThatCouldCauseExit();
}
catch (my_exit & me)
{
// Clean up globals now
exit(me());
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With