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.7] How can I convince my (older) compiler to automatically check new to see if it returns NULL?

Eventually your compiler will.

If you have an old compiler that doesn't automagically perform the NULL test, you can force the runtime system to do the test by installing a "new handler" function. Your "new handler" function can do anything you want, such as throw an exception, delete some objects and return (in which case operator new will retry the allocation), print a message and abort() the program, etc.

Here's a sample "new handler" that prints a message and throws an exception. The handler is installed using std::set_new_handler():

#include <new>       // To get std::set_new_handler
#include <cstdlib>   // To get abort()
#include <iostream>  // To get std::cerr

class alloc_error : public std::exception {
public:
  alloc_error() : exception() { }
};

void myNewHandler()
{
  // This is your own handler.  It can do anything you want.
  throw alloc_error();
}

int main()
{
  std::set_new_handler(myNewHandler);   // Install your "new handler"
  ...
}
After the std::set_new_handler() line is executed, operator new will call your myNewHandler() if/when it runs out of memory. This means that new will never return NULL:
Fred* p = new Fred();   // No need to check if p is NULL
Note: If your compiler doesn't support exception handling, you can, as a last resort, change the line throw ...; to:
std::cerr << "Attempt to allocate memory failed!" << std::endl;
abort();
Note: If some global/static object's constructor uses new, it might not use the myNewHandler() function since that constructor often gets called before main() begins. Unfortunately there's no convenient way to guarantee that the std::set_new_handler() will be called before the first use of new. For example, even if you put the std::set_new_handler() call in the constructor of a global object, you still don't know if the module ("compilation unit") that contains that global object will be elaborated first or last or somewhere inbetween. Therefore you still don't have any guarantee that your call of std::set_new_handler() will happen before any other global's constructor gets invoked.