Microsoft C++ allows you to specify what actions should be taken when the free store is exhausted. You do this by defining an error-handling function and passing it to the _set_new_handler function, defined in the include file NEW.H. Whenever the new operator supplied by the compiler cannot allocate the memory requested, it checks to see if an error handler has been installed. If an error handler is defined, new calls it; otherwise new simply returns zero. You can write a simple error handler that prints an error message, performs some cleanup tasks, and then exits the program, or you can write a more sophisticated error handler that attempts to recover memory so that new can retry the allocation.
The error handler you write must take the same arguments as the new function that invokes it. For the near or far free stores, the error handler must take one argument of type size_t, indicating the amount of memory requested, and return an integer. For the huge free store, the error handler must take an argument of type unsigned long, indicating the number of elements being allocated, and one of type size_t, indicating the size of each element. An error handler for the based free store must take an additional argument of type __segment, indicating the segment.
Summary: All error handlers require the __cdecl calling convention.
The error handler should return a zero if it is unable to recover the amount of memory requested. Otherwise, it should return a nonzero value. The __cdecl calling convention is required for all error handlers.
The following examples are sample prototypes for error handlers:
int my_near_handler( size_t size );
int my_far_handler( size_t size );
int my_huge_handler( unsigned long elems, size_t size );
int my_based_handler( __segment segvar, size_t size );
The _set_new_handler function maps onto either the _set_nnew_handler or _set_fnew_handler functions, depending on the program's memory model. You can also call these functions explicitly, or you can call the corresponding functions for the huge and based free stores. All of these functions return a pointer to the previously installed error handler, or a NULL if no handler was installed.
The following are prototypes for the functions that install the various error handlers. The types _PNH, _PNHH, and _PNHB are typedefs for pointers to the error-handling functions.
_PNH __cdecl _set_nnew_handler( _PNH handler );
_PNH __cdecl _set_fnew_handler( _PNH handler );
_PNHH __cdecl _set_hnew_handler( _PNHH handler );
_PNHB __cdecl _set_bnew_handler( _PNHB handler );
If the error handler returns a nonzero value, the new operator supplied by the compiler tries the allocation again. If the allocation fails again, new calls the error handler again. This continues until the error handler returns zero or until the allocation succeeds.
In multiprocess, multithreaded environments, separate error handlers exist for each process and thread. No handlers are preinstalled when a process begins. When a thread starts, it gets copies of its parent's handlers for all free stores.