|
||||
Section 16:
|
[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 NULLNote: 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. |