exception in a constructor



 DEVELOP > c-Plus-Plus > exception in a constructor

LINK TO THIS PAGE  


rating :  0   |  0


  Page 1 of 1

1

 
Topic: DEVELOP > c-Plus-Plus
User: "ES Kim"
Date: 04 Mar 2005 07:24:59 AM
Object: exception in a constructor
It's a common practice that you throw an exception in a constructor
when the invariant of the class is not met. But what if it's combined
with auto_ptr? I mean:
#include <memory>
using namespace std;
struct S
{
S(int i) { if (i < 0) throw "oops"; }
};
int main()
try
{
auto_ptr<S> ap(new S(-1)); // A
}
catch (...)
{
}
Statement A can be considered step by step like this:
(1) raw memory is allocated by ::operator new(sizeof(S))
(2) the memory is initialized by S::S(int)
(3) an auto_ptr is constructed pointing to the memory
But you see an exeption is thrown at step (2) and auto_ptr is
*not* constructed, which means ~auto_ptr is not called.
The net result is memory leak, of course.
What is a proper way to solve this kind of problem?
Let's not consider the possibility of bad_alloc. (If a bad_alloc
is thrown, there's no leak at least.)
--
ES Kim
.

User: "Siemel Naran"

Title: Re: exception in a constructor 04 Mar 2005 11:19:31 AM
"ES Kim" <no@spam.mail> wrote in message
news:d09nmj$qal$1@news1.kornet.net...

struct S
{
S(int i) { if (i < 0) throw "oops"; }
};

int main()
try
{
auto_ptr<S> ap(new S(-1)); // A
}
catch (...)
{
}

Statement A can be considered step by step like this:
(1) raw memory is allocated by ::operator new(sizeof(S))
(2) the memory is initialized by S::S(int)
(3) an auto_ptr is constructed pointing to the memory

Once step (2) throws, step (3) never happens, and the system calls steps
(1x)
(1x) raw memory is de-allocated by ::operator delete(void*)
Please note that the system does NOT call (2x) because (2) did not run to
completion
(2x) the memory is de-initialized by S::~S()
However, if class S had member variables and the initialization list ran to
completion and it was the constructor body that threw an exception, then
rest assured that the system will call the destructors of the member
variables constructed till the exception was thrown. If S had a base class,
then I'm not sure if the destructor of the base class would get called, but
I imagine it would because it is kind of like a member variable.
Note that if there was a class S::operator new, the system would call that
instead of the global operator new, and S::operator delete.

But you see an exeption is thrown at step (2) and auto_ptr is
*not* constructed, which means ~auto_ptr is not called.
The net result is memory leak, of course.
What is a proper way to solve this kind of problem?
Let's not consider the possibility of bad_alloc. (If a bad_alloc
is thrown, there's no leak at least.)

Your code is fine.
.

User: "Dietmar Kuehl"

Title: Re: exception in a constructor 04 Mar 2005 07:35:35 AM
ES Kim wrote:

auto_ptr<S> ap(new S(-1)); // A
Statement A can be considered step by step like this:
(1) raw memory is allocated by ::operator new(sizeof(S))
(2) the memory is initialized by S::S(int)
(3) an auto_ptr is constructed pointing to the memory
But you see an exeption is thrown at step (2) and auto_ptr is
*not* constructed, which means ~auto_ptr is not called.
The net result is memory leak, of course.

The people creating the C++ standard thought of this: if an exception
is thrown during step 2, all members constructed so far are destroyed
and then 'operator delete()' is called appropriately (i.e., if you
used a placement form of new, a corresponding placement delete would
be called).

What is a proper way to solve this kind of problem?

You don't care about it because it is not your concern: it is the
compiler implementers concern.

Let's not consider the possibility of bad_alloc. (If a bad_alloc
is thrown, there's no leak at least.)

Nor is there if the constructor of the object throws an exception.
--
<mailto:dietmar_kuehl@yahoo.com> <http://www.dietmar-kuehl.de/>
<http://www.contendix.com> - Software Development & Consulting
.
User: "ES Kim"

Title: Re: exception in a constructor 04 Mar 2005 08:07:55 AM
"Dietmar Kuehl" <dietmar_kuehl@yahoo.com> wrote in message
news:1109943335.369066.112290@o13g2000cwo.googlegroups.com...

ES Kim wrote:

auto_ptr<S> ap(new S(-1)); // A


Statement A can be considered step by step like this:
(1) raw memory is allocated by ::operator new(sizeof(S))
(2) the memory is initialized by S::S(int)
(3) an auto_ptr is constructed pointing to the memory
But you see an exeption is thrown at step (2) and auto_ptr is
*not* constructed, which means ~auto_ptr is not called.
The net result is memory leak, of course.


The people creating the C++ standard thought of this: if an exception
is thrown during step 2, all members constructed so far are destroyed
and then 'operator delete()' is called appropriately (i.e., if you
used a placement form of new, a corresponding placement delete would
be called).

That's reassuring, and I found the relevent phrase in the Standard.
Thank you.
--
ES Kim
.


User: ""

Title: Re: exception in a constructor 04 Mar 2005 01:58:11 PM
There's an MSDN article that explains this issue quite well:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dndeepc/html/deep090799.asp
.


  Page 1 of 1

1

 


Related Articles
 

NEWER

pg.1232     pg.940     pg.716     pg.544     pg.412     pg.311     pg.234     pg.175     pg.130     pg.96     pg.70     pg.50     pg.35     pg.24     pg.16     pg.10     pg.6     pg.3     pg.1

OLDER