C++ FAQ Celebrating Twenty-One Years of the C++ FAQ!!!
(Click here for a personal note from Marshall Cline.)
Section 16:
16.1 Does delete p delete the pointer p, or the pointed-to-data *p?
16.2 Is it safe to delete the same pointer twice?
16.3 Can I free() pointers allocated with new? Can I delete pointers allocated with malloc()?
16.4 Benefits of new over malloc()?
16.5 Can I use realloc() on pointers allocated via new?
16.6 Checking for NULL after p = new Fred()?
16.7 How can I convince my (older) compiler to automatically check new to see if it returns NULL?
16.8 Checking for NULL before delete p?
16.9 What are the two steps that happen when I say delete p?
16.10 Does p = new Fred() leak memory if the ctor throws an exception?
16.11 How do I allocate / unallocate an array of things?
16.12 What if I forget the [] when deleteing an array allocated via new T[n]?
16.13 Can I drop the [] when deleteing an array of some built-in type (char, int, etc)?
16.14 After p = new Fred[n], how does the compiler know there are n objects to be destructed during delete[] p?
16.15 Is it legal (and moral) for a member function to say delete this?
16.16 How do I allocate multidimensional arrays using new?
16.17 How to simplify the Matrix code from the previous FAQ?
16.18 How to make the Matrix class generic?
16.19 What's another way to build a Matrix template?
16.20 Does C++ have arrays whose length can be specified at run-time?
16.21 Allocating all objects via new, not local/global/static?
16.22 How do I do simple reference counting?
16.23 How do I provide reference counting with copy-on-write semantics?
16.24 How do I provide reference counting with copy-on-write semantics for a hierarchy of classes?
16.25 Preventing people from subverting the reference counting mechanism?
16.26 Can I use a garbage collector in C++?
16.27 What are the two kinds of garbage collectors for C++?
16.28 Where can I get more info on garbage collectors for C++?
[16.10] In p = new Fred(), does the Fred memory "leak" if the Fred constructor throws an exception?

No.

If an exception occurs during the Fred constructor of p = new Fred(), the C++ language guarantees that the memory sizeof(Fred) bytes that were allocated will automagically be released back to the heap.

Here are the details: new Fred() is a two-step process:

  1. sizeof(Fred) bytes of memory are allocated using the primitive void* operator new(size_t nbytes). This primitive is similar in spirit to malloc(size_t nbytes). (Note, however, that these two are not interchangeable; e.g., there is no guarantee that the two memory allocation primitives even use the same heap!).
  2. It constructs an object in that memory by calling the Fred constructor. The pointer returned from the first step is passed as the this parameter to the constructor. This step is wrapped in a try ... catch block to handle the case when an exception is thrown during this step.

Thus the actual generated code is functionally similar to:

// Original code: Fred* p = new Fred();
Fred* p;
void* tmp = operator new(sizeof(Fred));
try {
  new(tmp) Fred();  // Placement new
  p = (Fred*)tmp;   // The pointer is assigned only if the ctor succeeds
}
catch (...) {
  operator delete(tmp);  // Deallocate the memory
  throw;                 // Re-throw the exception
}
The statement marked "Placement new" calls the Fred constructor. The pointer p becomes the this pointer inside the constructor, Fred::Fred().