The C function malloc returns NULL when it cannot allocate the requested amount of memory. When programming in C, it is good practice to check for a NULL return value every time you call malloc. This way your program can exit gracefully instead of crashing as a result of trying to dereference a NULL pointer.
Similarly, the new operator returns 0 when it cannot allocate the requested amount of memory. Just as in C, you can check for a 0 return value every time you call new. However, C++ provides a more convenient alternative in the _set_new_handler function (declared in the include file NEW.H).
The _set_new_handler function takes a function pointer as an argument. This pointer must point to an error-handling function that you write. By calling _set_new_handler, you install this function as the error-handler for the free store. When new cannot allocate the memory requested, it checks to see if an error-handler has been installed. If no error-handler is installed (which is the default), new returns 0. If you have installed an error-handler, new calls it.
You can write a simple error-handling function that prints an error message and exits the program. For example:
// Free store exhaustion and the _set_new_handler function
#include <iostream.h>
#include <stdlib.h>
#include <new.h>
int all_gone( size_t size )
{
cerr << "\n\aThe free store is empty\n";
exit( 1 );
return 0;
}
void main()
{
_set_new_handler( all_gone );
long total = 0;
while( 1 )
{
char *gobble = new char[10000];
total += 10000;
cout << "Got 10000 for a total of " << total << '\n';
}
}
This example executes a loop that consumes memory and displays the total amount of memory currently allocated. When new cannot allocate any more memory, it calls the all_gone function, which prints an error message and exits. Note that the all_gone function takes a parameter of type size_t, which represents the size of the block requested when new failed, and that it returns an integer. Any error-handling function you write must have this parameter and return type.
The above example might print the following messages, depending on how much memory is available:
Got 10000 for a total of 10000
Got 10000 for a total of 20000
Got 10000 for a total of 30000
Got 10000 for a total of 40000
Got 10000 for a total of 50000
The free store is empty
An error-handling function like this removes the need for you to check the return value of new every time you call it. You can write code to handle the possibility of memory exhaustion in just one place, rather than throughout your program.