allocate on the heap when using exception

T

Tony Johansson

Hello!

When you allocate object dynamically which mean on the heap I find that a
problem when using exception.
What is the prefer method to handle this kind of problem.

//Tony
 
R

Rolf Magnus

Tony said:
Hello!

When you allocate object dynamically which mean on the heap I find that a
problem when using exception.
Why?

What is the prefer method to handle this kind of problem.

It's unclear what problem you are referring to.
 
A

Alan Johnson

Tony said:
Hello!

When you allocate object dynamically which mean on the heap I find that a
problem when using exception.
What is the prefer method to handle this kind of problem.

//Tony

If I understand what you are asking, then you want an auto_ptr. Example:

#include <memory>

class A { ... } ;
class B { ... } ;
class C { ... } ;

....
std::auto_ptr<A> pa(new A) ;
std::auto_ptr<B> pb(new B) ;
std::auto_ptr<C> pc(new C) ;
....

When pa, pb, and pc have their destructors called, they will delete the
memory that they "own". The important part here is that pa, pb, and pc
are NOT dynamically allocated, so if an exception is thrown, you are
guaranteed that their destructors are called appropriately.

This web site gives some useful information:
http://www.gotw.ca/gotw/042.htm

One rather important thing to keep in mind is that you cannot put an
auto_ptr in a standard container (the standard containers require their
value types to be Assignable, a set of obligations which auto_ptr does
not fulfill).

-Alan
 
P

Peter Julian

Tony Johansson said:
Hello!

When you allocate object dynamically which mean on the heap I find that a
problem when using exception.
What is the prefer method to handle this kind of problem.

There is no problem, its your responsability to catch the generated
exception at the level of your choice (a failed new throws a std::bad_alloc
exception). Its also your responsability to write code that doesn't generate
memory leaks so as not to find yourself in a situation where new allocations
fail. The same goes for virtual destructors in the case inheritence is
involved (a failed allocation needs to invoke the base class d~tors).

The problem, in fact, is understanding what happens when an exception is
indeed thrown. Not catching the exception *unwinds* the present scope off
the call stack and passes the exception object up to next level. If next
scope level doesn't handle the exception, that scope is unwound and the
original exception object is passed up again. This process continues until
either the exception object is caught or an unexpected exception handler
catches it.

To explain the exception-object passing unwind mechanism, consider a class N
that throws a std::bad_alloc exception in its ctor when its member is set to
2. I'm artificially throwing a new allocation failure when N *p_n2 = new
N(2) is invoked.

Note how the last 2 objects don't get constructed and therefore never get
destroyed. Throwing the std::bad_alloc exception object mimics what happens
when the allocation actually fails at runtime.

#include <iostream>
#include <stdexcept>

class N
{
int n;
public:
N(int nn) : n(nn)
{
if (2 == n) // testing std::bad_alloc exception
{
std::cout << "ctor unwind !!!\n";
throw std::bad_alloc("std::bad_alloc exception object\n");
}
std::cout << "N ctor invoked\n";
}
~N()
{
std::cout << "N d~tor invoked\n";
}
}; // class N

int main(int argc, char* argv[])
{
N *p_n0 = 0;
N *p_n1 = 0;
N *p_n2 = 0;
N *p_n3 = 0;

try
{
p_n0 = new N(0);
p_n1 = new N(1);
p_n2 = new N(2); // will throw
p_n3 = new N(3);
}
catch(const std::bad_alloc& e)
{
std::cout << "Error: " << e.what();
}

if (0 != p_n0)
delete p_n0;
if (0 != p_n1)
delete p_n1;
if (0 != p_n2)
delete p_n2;
if (0 != p_n3)
delete p_n3;

return 0;
}

/*
N ctor invoked
N ctor invoked
ctor unwind !!!
Error: std::bad_alloc exception object
N d~tor invoked
N d~tor invoked
*/

Note how the third object (*p_n2) is never allocated and the fouth
allocation (*p_n3) is never attempted.
Now, what happens if i don't wrap the new allocations in main() in a
try-catch block? Test 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

Forum statistics

Threads
474,204
Messages
2,571,066
Members
47,672
Latest member
svaraho

Latest Threads

Top