delete p is a two-step process: it calls the destructor, then releases the
memory. The code generated for delete p is functionally similar to this (assuming
p is of type Fred*):
// Original code: delete p;
if (p != NULL) {
p->~Fred();
operator delete(p);
}
The statement
p->~Fred() calls the destructor for the
Fred object
pointed to by
p.
The statement operator delete(p) calls the memory deallocation
primitive, void operator delete(void* p). This primitive is similar in
spirit to free(void* p). (Note, however, that these two are
not interchangeable; e.g., there is no guarantee that the two memory
deallocation primitives even use the same heap!)