How to deallocate memory when handling exception

T

Tony Johansson

Hello Experts!

Assume foo is a method in a some class or a stand-alone function and method
push is throwing an exception of class logic_error.
Assume also that I want to handle this exception in foo if it's possible.
This will cause a problem because C++ doesn't have the finally keyword and I
can't do delete both in the exception handler and after the exception
handler that's because I have put in the throw to throw it further
to let some other method to handle it. But if I remove this throw how is it
then possible to get a
solution that will hold and i a good solution. If I just remove this throw
and an exception occurs will this cause delete s two times and resuting in
undefined behaviour.

void foo()
{
IntStack* s

try
{
s = new IntStack(20);
s->push(20);
}
catch(const logic_error& e)
{
delete s;
throw; //
}

delete s;
}

Many thanks

//Tony
 
G

Gianni Mariani

Tony said:
Hello Experts!

Assume foo is a method in a some class or a stand-alone function and method
push is throwing an exception of class logic_error.
Assume also that I want to handle this exception in foo if it's possible.
This will cause a problem because C++ doesn't have the finally keyword and I
can't do delete both in the exception handler and after the exception
handler that's because I have put in the throw to throw it further
to let some other method to handle it. But if I remove this throw how is it
then possible to get a
solution that will hold and i a good solution. If I just remove this throw
and an exception occurs will this cause delete s two times and resuting in
undefined behaviour.

void foo()
{
IntStack* s;
Note that s is uninitialized - could contain garbage.
try
{
s = new IntStack(20);
new can throw badalloc - s may not get set - still contains garbage.
s->push(20);
}
catch(const logic_error& e)
{
delete s;
throw; //
}

delete s;

Trying to delete garbage. Not good 10 out of 10.

Another problem, is if push throws some other (possibly future)
exception type, you will leak s.

To answer the OP question, I would use the RAII idion (Resource
Aquisition Is Initialization) and remove the need to handle this type of
logic manually.

#include <list>
#include <memory>

typedef std::list<int> IntStack;
struct logic_error {};

void foo()
{
std::auto_ptr<IntStack> s;

try
{
s.reset( new IntStack(20) );
s->push_back(20);
}
catch(const logic_error& e)
{
throw; //
}

}

OK - so you don't like that ? This will work too. Although, the code
above looks alot simpler and much more intuitive.

void foo()
{
IntStack* s = 0;

try
{
try
{
s = new IntStack(20);
s->push(20);
}
catch(const logic_error& e)
{
delete s;
s = 0;
if ( cant_fix_logic )
{
throw; //
}
}
} catch (...)
{
delete s;
throw;
}

delete s;
}
 
P

Pete Becker

Gianni said:
To answer the OP question, I would use the RAII idion (Resource
Aquisition Is Initialization) and remove the need to handle this type of
logic manually.

std::auto_ptr<IntStack> s;

Just to underscore the point: this is exactly what auto_ptr was designed
for.
 
O

Old Wolf

Gianni said:
#include <list>
#include <memory>

typedef std::list<int> IntStack;
struct logic_error {};

void foo()
{
std::auto_ptr<IntStack> s;

try
{
s.reset( new IntStack(20) );
s->push_back(20);
}
catch(const logic_error& e)
{
throw; //
}

}

OK - so you don't like that ? This will work too. Although, the code
above looks alot simpler and much more intuitive.

Equivalent and even simpler:

void foo()
{
IntStack s(20);
s.push_back(20);
}

Remarkably, your code does the first 2 things listed on the
'pet peeves' thread on c.l.c++.moderated, ie. using 'new'
and 'delete' instead of creating an automatic object,
and catching something only to rethrow it.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top