Thanks for all the response.
I reformatted my question to understand the state of the member pointer after the containg class constructor throws an exception
There is a similar question here that covers what your asking.
In this case, if the call to new
fails, then the memory for the pointer is guaranteed to be freed. If the call succeeds, and the constructor throws after that, you will have a memory leak.
The destructor of the class will not be called, because the object was never fully constructed. There are two ways to fix this.
1)
Have exceptions fully managed in the constructor:
class Foo
{
public:
Foo()
try
{
p = new p;
throw /* something */;
}
catch (...)
{
delete p;
throw; //rethrow. no memory leak
}
private:
int *p;
};
2)
Or use a smart pointer. When a constructor is entered, all of its members have been constructed. And because when a constructor throws, and objects members have been constructed, they must be destructed. And a smart pointer fixes that:
class Foo
{
public:
Foo() :
p(new int)
{
throw /* something */;
}
private:
std::auto_ptr<int> p;
};
The question really doesn't make any sense. new Fred();
will never return NULL. It will only ever either successfully create a Fred object, or throw an exception. If it threw an exception, the Fred object would never have existed, so it's destructor would not be called.
Not if it was never allocated.
But instead of NULL
being returned by bad allocations via new, you will get an exception std::bad_alloc.
NULL
gets returned by C malloc if an allocation cannot be made.
You are also correct that if an object is not fully constructed, it will not be destructed. So if you have a successful allocation on the heap in a constructor, and then an exception is thrown, that will lead to a memory leak.
You could also consider having a zombie state instead of throwing an exception. Some of the standard C++ library does this. In which case the object is not in a valid state and can be checked if it is in a valid state via another method.
Generally throwing exceptions in constructors is best though.
See my answer here for an extended discussion.
The destructor for p
will not be called, if the memory allocation for p
fails.