Constructor throws?

I

indrawati.yahya

According to the FAQ, the best way to inform a class user of an error
that occurs inside a constructor is to throw an exception. My question
is, what happens when an object is instantiated using 'new', and the
constructor throws after 'new' allocates memory for that object? Will
the memory leak? Thanks.
 
K

Kai-Uwe Bux

According to the FAQ, the best way to inform a class user of an error
that occurs inside a constructor is to throw an exception. My question
is, what happens when an object is instantiated using 'new', and the
constructor throws after 'new' allocates memory for that object? Will
the memory leak? Thanks.

I think, it's a quality of implementation issue. Clause [5.3.4/8] _allows_
the implementation to do the right thing:

A new-expression obtains storage for the object by calling an allocation
function (3.7.3.1). If the newexpression terminates by throwing an
exception, it may release storage by calling a deallocation function
(3.7.3.2) ...

That said, I would hope (and assume) that you will have a hard time finding
an implementation where memory leaks in this case.

You could run the following and monitor its storage usage with OS tools:

#include <iostream>

struct X {

char data [8192];

X ( void ) {
throw ( 1 );
}

};

int main ( void ) {
while ( true ) {
try {
X* x_ptr = new X;
}
catch ( ... ) {
std::cout << '.';
}
}
}


Best

Kai-Uwe Bux
 
J

James Kanze

According to the FAQ, the best way to inform a class user of an error
that occurs inside a constructor is to throw an exception. My question
is, what happens when an object is instantiated using 'new', and the
constructor throws after 'new' allocates memory for that object? Will
the memory leak?

If it is a non-placement new, the global operator delete
function will be called for the memory. (Watch out for memory
that was allocated within the constructor before throwing,
however.) If it is a placement new, and a corresponding
placement operator delete function exists, it will be called.
If no corresponding placement operator delete function has been
declared, the compiler assumes that it isn't necessary. (For
some reason, the standard defines a no-op placement operator
delete function for the standard placement new, rather than
count on the fact that if there is no corresponding placement
operator delete function, the compiler will do nothing. I
suppose it does prevent the user from accidentally defining one
that does something, but I'll admit that users accidentally
defining a placement delete that shouldn't have been defined has
not been a major cause of error in the code that I've seen.)
 
P

Peter

According to the FAQ, the best way to inform a class user of an error
that occurs inside a constructor is to throw an exception. My question
is, what happens when an object is instantiated using 'new', and the
constructor throws after 'new' allocates memory for that object? Will
the memory leak? Thanks.


the memory is freed automatically. This is easy to check.

Using exceptions to terminate constructors is very elegant.
Think about the horrible solutions people invented before exceptions
were introduced.
Now you can have a fallible resource allocation inside a constructor.
Some suggestions:

* perform only a single resource allocation inside a constructor.
If you perform more than one allocation inside a constructor you will
have to deal with cleanup yourself in case of one of the allocation
fails. Remember that destructors are only called for successfully
constructed objects (which have not been aborted by a exception
thrown). If you throw in a constructor of a class which has base-
classes or member-classes, the destructors for the successfully
constructed base-classes or member-classes are called.
* resource allocation is everything which is paired:
Creating a window/destroying a window
Opening a file/closing a file
mapping a file/unmapping a file
setting a handler/restoring the original handler
showing a window/hiding a window
creating a (bitmap) handle, destroying this (bitmap) handle
* throw an exception if the matching allocation fails. This exception
should contain all necessary information -- e.g. system error
information to give rich error information
* chain such single allocation classes into more complex classes using
base-class/member class relationships
 
K

Kai-Uwe Bux

Kai-Uwe Bux said:
According to the FAQ, the best way to inform a class user of an error
that occurs inside a constructor is to throw an exception. My question
is, what happens when an object is instantiated using 'new', and the
constructor throws after 'new' allocates memory for that object? Will
the memory leak? Thanks.

I think, it's a quality of implementation issue. Clause [5.3.4/8] _allows_
the implementation to do the right thing:

A new-expression obtains storage for the object by calling an allocation
function (3.7.3.1). If the newexpression terminates by throwing an
exception, it may release storage by calling a deallocation function
(3.7.3.2) ...

Correcting myself: it's not a quality of implementation issue. I had missed
clause [5.3.4/17]:


If any part of the object initialization described above terminates by
throwing an exception and a suitable deallocation function can be found,
the deallocation function is called to free the memory in which the object
was being constructed, after which the exception continues to propagate in
the context of the newexpression. If no unambiguous matching deallocation
function can be found, propagating the exception does not cause the
object?s memory to be freed. [Note: This is appropriate when the called
allocation function does not allocate memory; otherwise, it is likely to
result in a memory leak. ]


Best

Kai-Uwe Bux
 

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,780
Messages
2,569,611
Members
45,280
Latest member
BGBBrock56

Latest Threads

Top