Search code examples
c++classexceptiondelete-operator

Delete operator segfaults when the constructor throws an exception


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.


Solution

  • 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. [...]