In some circumstances, corrective action can be taken during memory allocation and the request can be fulfilled. To gain control when the global operator new function fails, use the _set_new_handler function (defined in NEW.H) as follows:
#include <stdio.h>
#include <new.h>
// Define a function to be called if new fails to allocate memory.
int MyNewHandler( size_t size )
{
clog << "Allocation failed. Coalescing heap." << endl;
// Call a fictitious function to recover some heap space.
return CoalesceHeap();
}
void main()
{
// Set the failure handler for new to be MyNewHandler.
_set_new_handler( MyNewHandler );
int *pi = new int[BIG_NUMBER];
}
In the preceding example, the first statement in main sets the new handler to MyNewHandler
. The second statement tries to allocate a large block of memory using the new operator. When the allocation fails, control is transferred to MyNewHandler
. The argument passed to MyNewHandler
is the number of bytes requested. The value returned from MyNewHandler
is a flag indicating whether allocation should be retried: a nonzero value indicates that allocation should be retried, and a zero value indicates that allocation has failed.
MyNewHandler
prints a warning message and takes corrective action. If MyNewHandler
returns a nonzero value, the new operator retries the allocation. When MyNewHandler
returns a 0 the new operator stops trying and returns a zero value to the program.
The _set_new_handler function returns the address of the previous new handler. Therefore, if a new handler needs to be installed for a short time, the previous new handler can be reinstalled using code such as the following:
#include <new.h>
...
_PNH old_handler = _set_new_handler( MyNewHandler );
// Code that requires MyNewHandler.
...
// Reinstall previous new handler.
_set_new_handler( old_handler );
A call to _set_new_handler with an argument of 0 causes the new handler to be removed. There is no default new handler.
The new handler you specify can have any name, but it must be a function returning type int (nonzero indicates the new handler succeeded, and zero indicates that it failed).
If a user-defined operator new is provided, the new handler functions are not automatically called on failure.
The prototype for _set_new_handler and the type _PNH is defined in NEW.H:
_PNH _set_new_handler( _PNH );
The type _PNH is a pointer to a function that returns type int and takes a single argument of type size_t.