Running out of storage
What happens when the operator new(
) cannot find a
contiguous block of storage large enough to hold the desired object? A special
function called the new-handler is called. Or
rather, a pointer to a function is checked, and if the pointer is nonzero, then
the function it points to is called.
The default behavior for the new-handler
is to throw an exception, a subject covered in
Volume 2. However, if you’re using heap allocation in your program,
it’s wise to at least replace the new-handler with a message that says
you’ve run out of memory and then aborts the program. That way, during
debugging, you’ll have a clue about what happened. For the final program
you’ll want to use more robust recovery.
You replace the new-handler by including
new.h and then calling set_new_handler( ) with the address of
the function you want installed:
//: C13:NewHandler.cpp
// Changing the new-handler
#include <iostream>
#include <cstdlib>
#include <new>
using namespace std;
int count = 0;
void out_of_memory() {
cerr << "memory exhausted after " << count
<< " allocations!" << endl;
exit(1);
}
int main() {
set_new_handler(out_of_memory);
while(1) {
count++;
new int[1000]; // Exhausts memory
}
} ///:~
The new-handler function must take no
arguments and have a void return value. The while loop will keep
allocating int objects (and throwing away their return addresses) until
the free store is exhausted. At the very next call to new, no storage can
be allocated, so the new-handler will be called.
The behavior of the new-handler is tied
to operator new( ), so if you overload operator new(
) (covered in the next section) the new-handler will not be called by
default. If you still want the new-handler to be called you’ll have to
write the code to do so inside your overloaded operator new(
).
Of course, you can write more
sophisticated new-handlers, even one to try to reclaim memory (commonly known as
a garbage collector). This is not a job for the
novice
programmer.