I have my smart pointer implementation as bellow which is NOT deallocating memory at exceptions ..
template <class T>
class SMARTPOINTER
{
public:
SMARTPOINTER(T* pointee) : SMART_POINTEE(pointee) {
cout <<"\n Inside class SMARTPOINTER CONSTURCTOR \n";
}
~SMARTPOINTER() {
cout <<"\n Inside class SMARTPOINTER DESTRUCTOR \n";
delete SMART_POINTEE;
}
T& operator*() const
{
cout <<"\n Inside class SMARTPOINTER operator* \n";
return *SMART_POINTEE;
}
T* operator->() const
{
cout <<"\n Inside class SMARTPOINTER operator->() \n";
return SMART_POINTEE;
}
private:
T* SMART_POINTEE;
};
class Widget
{
public:
Widget() {
cout <<"\n Inside Widget CONSTRUCTOR \n";
}
void Fun() {
cout <<"\n Inside Widget::Fun() \n";
}
~Widget() {
cout <<"\n Inside Widget DESTRUCTOR \n";
}
};
class THROWME{
};
int main() {
SMARTPOINTER<Widget> sp(new Widget);
sp->Fun();
throw new THROWME;
(*sp).Fun();
return 0 ;
}
I find that the output is
Inside Widget CONSTRUCTOR
Inside class SMARTPOINTER CONSTURCTOR
Inside class SMARTPOINTER operator->()
Inside Widget::Fun()
uncaught exception of type THROWME*
Aborted.
As far as I know Smart pointers are supposed to help me in such cases!! I do not find destruction of Widget getting called via smart pointer .
So I must be missing some implementation here .
EDIT AFTER COMMENTS READ
With try catch i got my result . But i still dont know if its right approach change in code
int main() {
try {
SMARTPOINTER<Widget> sp(new Widget);
sp->Fun();
THROWME tm;
throw tm;
(*sp).Fun();
}
catch(...) {
cout <<"\n **SOME EXCEPTION CAUGHT** \n";
}
return 0 ;
}
result
Inside Widget CONSTRUCTOR
Inside class SMARTPOINTER CONSTURCTOR
Inside class SMARTPOINTER operator->()
Inside Widget::Fun()
Inside class SMARTPOINTER DESTRUCTOR
Inside Widget DESTRUCTOR
**SOME EXCEPTION CAUGHT**
The destructor is not being called as the unhandled exception THROWME causes std::terminate to be called. See also this question, specifically the first quotation in the accepted answer:
C++11 15.2 Constructors and destructors [except.ctor]
1 As control passes from a throw-expression to a handler, destructors are invoked for all automatic objects constructed since the try block was entered. The automatic objects are destroyed in the reverse order of the completion of their construction.
As you have no try block to handle the exception, no destructor is called.
Calling of the destructor is part of stack unwinding, which is done when the exception "bubbles up" the call stack... except when the exception is unhandled. In that case, whether or not the stack is unwound is implementation-defined:
If no matching handler is found in a program, the function
terminate()(except.terminate) is called. Whether or not the stack is unwound before callingterminate()is implementation-defined.
To handle this more gracefully, you could use a function try block:
int main()
try {
// main body
} catch (...) {
std::cerr << "Unhandled exception\n";
std::terminate();
}
... although this will swallow the exception and make it hard to debug.
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