Best to start with code to get an understanding of this
#include "Hello1.h"
#include "Hello2.h"
int main(int argc, char ** argv)
{
// Hello1 and Hello2 are derevied classes of Hello
// And there constructor throws an exception
Hello * h;
try
{
if (argv[1][0]=='1')
h = new Hello1;
else
h = new Hello2;
}
catch (std::exception ex) { /*print error*/ }
delete h;
}
If Hello1
and Hello2
throws an exception, It segfault. However If I add
Hello h = NULL;
It works!!!
Hello is a class with a constructor that throw's an exception
All I can think of is that the exceptions in constructor's remove the object from memory! Why where who...Explain! Please.
However If I add
Hello h = NULL;
it works!!! Why where who...Explain! Please.
That is because operator delete
does nothing when the pointer is null
. It is expected to do nothing, that's standard behavior. Paragraph 3.7.4.2 of the C++11 Standard specifies:
[...] The value of the first argument supplied to a deallocation function may be a null pointer value; if so, and if the deallocation function is one supplied in the standard library, the call has no effect. [...]
If it is not null
, on the other hand, operator delete
will try to delete the object pointed to by hello
, and since the pointer is uninitialized (because construction threw and control was transferred to the exception handler before the assignment to hello
happened), you get undefined behavior.
Per paragraph 5.3.5/2:
[...] In the first alternative (delete object), the value of the operand of
delete
may be a null pointer value, a pointer to a non-array object created by a previous new-expression, or a pointer to a subobject (1.8) representing a base class of such an object (Clause 10). If not, the behavior is undefined. [...]