Why exception in destructor is a bad idea?

Share the Article

Destructor case:

Exception in destructor are dangerous. Firstly the exception here may cause the abnormal termination of C++ program. This can happen when object may go out of its scope. However, if the program has written sufficient catch blocks and it manages to survive, then also it is problematic. Basically, this may still cause memory leaks or resource leaks and potentially may cause undefined behavior.

Memory Leak Example

#include <iostream> //main header using namespace std; //namespace class MainFunda { int iindex; public: MainFunda(int ix) : iindex(ix) { cout << "MainFunda() constructor : " << iindex << endl; } ~MainFunda() { if(iindex >= 4) throw; //Throwing exception cout << "~MainFunda() Destructor : " << iindex << endl; } }; int main() { std::vector<MainFunda> av; av.reserve(5); for (int ik=1; ik<=5; ik++) { MainFunda* tmp = new MainFunda(ik); av.push_back(*tmp); } cout << "vector going out-of-scope" << endl; return 0; }

In above program, construction happens for 5 objects, but destruction happen for only 3 objects. The fourth and fifth object do not get destroyed. This is because, exception ultimately is happening in destructor of vector. Therefore, after the exception, rest of the destruction is skipped.

Output:

terminate due to exception thrown in destructor

Exception Handling in destructor:

Any task that may cause exception should not be performed without proper exception handling. The exception handler should either gracefully terminate the program or swallow the exception. In no case, the program should allow an exception to leave destructor.

The following example now has added proper try-catch block in same program. This shall catch the exception during destruction of fourth and fifth object.

#include <iostream> //main header #include <vector> //for stl vector using namespace std; //namespace class MainFunda { int iindex; public: MainFunda(int ix) : iindex(ix) { cout << "MainFunda() constructor : " << iindex << endl; } ~MainFunda() { try { if(iindex >= 4) throw iindex; cout << "~MainFunda() Destructor : " << iindex << endl; } catch(int ii) { cout << "Failed Destructor : " << ii << endl; } } }; int main() { std::vector<MainFunda> av; av.reserve(5); for (int i=1; i<=5; i++) { MainFunda* tmp = new MainFunda(i); av.push_back(*tmp); } cout << "vector going out-of-scope" << endl; return 0; }

The destructor of class MainFunda has handled the exception. Therefore, the destruction of vector shall complete now. The output clearly shows that all the objects are getting destroyed.

using try catch block in destructor so that exception should not leave the function

Main Funda: Program should never allow any exceptions go unhandled in destructor. The program must handle them properly inside destructor

Related Topics:

Why a destructor should never throw exception? 
What is the problem with setjmp( ) & longjmp( ) ? 
Basics of throwing and catching exception 
Why should we catch an exception object, using reference-parameter?
What happens when exception thrown from a constructor?
Re-throwing an exception 
What are function level try-catch blocks 
Understanding exception specification for functions 
Explaining C++ casts 
How pointer to class members are different ? 
What is reference collapsing?
How to make a class object un-copyable?

Share the Article

Leave a Reply

Your email address will not be published. Required fields are marked *