Suppose I have a class like this:
#include <iostream>
using namespace std;
class Boda {
private:
char *ptr;
public:
Boda() {
ptr = new char [20];
}
~Boda() {
cout << "calling ~Boda\n";
delete [] ptr;
}
void ouch() {
throw 99;
}
};
void bad() {
Boda b;
b.ouch();
}
int main() {
bad();
}
It seems that destructor ~Boda
never gets called, thus the ptr
resource never get freed.
Here is the output of the program:
terminate called after throwing an instance of 'int'
Aborted
So it seems the answer to my question is No
.
But I thought that the stack got unwound when an exception got thrown? Why didn't Boda b
object get destructed in my example?
Please help me understand this resource problem. I want to write better programs in the future.
Also, is this the so called RAII
?
Thanks, Boda Cydo.
If the exception is not caught anywhere, then the C++ runtime is free to go straight to terminating the program without doing any stack unwinding or calling any destructors.
However, if you add a try-catch block around the call to bad()
, you will see the destructor for the the Boda
object being called:
int main() {
try {
bad();
} catch(...) { // Catch any exception, forcing stack unwinding always
return -1;
}
}
RAII means that dynamically (heap) allocated memory is always owned by an automatically (stack) allocated object that deallocates it when the object destructs. This relies on the guarantee that the destructor will be called when the automatically-allocated object goes out of scope, whether due to a normal return or due to an exception.
This corner-case behavior is normally not a problem with respect to RAII, since usually the main reason that you want the destructors to run is to free memory, and all memory is given back to the OS when your program terminates anyway. However if your destructors do something more complicated, like maybe remove a lock file on disk or something, where it would make a difference whether the program called destructors or not when crashing, you may want to wrap your main
in a try-catch block that catches everything (only to exit on exception anyway) just to ensure that the stack always unwinds before terminating.
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