Reputation: 256
I have just started using c++ boost libraries. I read in many places that when a scoped_ptr is used then the object is always destroyed even in case of exceptions.
I tried in the following code.
#include<boost/scoped_ptr.hpp>
class B
{
public:
B(){ std::cout<< "B constructor call\n"; }
~B(){ std::cout<<"B destructor call\n"; }
};
class A
{
public:
boost::scoped_ptr<B> b;
A():b(new B())
{
throw 1;
}
};
int main()
{
A a; return 0;
}
output:
B constructor call
terminate called after throwing an instance of 'int'
Aborted (core dumped)
There is no call to B's destructor. But I used scoped_ptr so it should have called B's destructor or did I mis-interpreted the use of scoped_ptr.
But if a surround it with try catch then B's destructor is called.
try{
A a;
} catch( ... ) {
}
In this case destructor of A will be called as all locally allocated objects in case of exception in a try block are removed from the stack and I have my pointer wrapped inside and object of scoped_ptr so when the destructor of scoped object destroys which ultimately the pointer. So is scoped_ptr is useful because we don't have to explicitly delete the memory allocated or I mis-interpreted the description of scoped_ptr.
How can I call the destructor of class B in case of exception using scoped_ptr
Upvotes: 6
Views: 721
Reputation: 6914
C++ destroy a local variable when unwinding stack(return from a function, either with return
keyword or with an exception), so it should see one to destroy your scoped_ptr
. But in your special case, exception occurred in main
so terminate
will be called and kill your program before C++ unwind the stack.
void test() {throw 1;}
void main() {
string sMain;
test();
}
In above example, sMain
will not destroyed because exception cause calling terminate
:
sMain constructed
exception occurred: main has no where to go, and it has no handler to handle
the exception, so it will call `terminate`, but wait we are still at `main`
so we have no stack unwinding here and sMain will never destroyed!!
Upvotes: 0
Reputation: 62975
There's no matching exception handler, so std::terminate
is called directly, in this case without the stack being unwound. Put a try
/catch
in main
that catches int
and you'll see your destructor call, even if that handler rethrows.
C++11 §15.1/2:
When an exception is thrown, control is transferred to the nearest handler with a matching type; "nearest" means the handler for which the compound-statement or ctor-initializer following the
try
keyword was most recently entered by the thread of control and not yet exited.
and §15.3/9:
If no matching handler is found, the function
std::terminate()
is called; whether or not the stack is unwound before this call tostd::terminate()
is implementation-defined.
Upvotes: 15