¿Qué ocurre cuando new()
no puede encontrar un bloque contiguo
suficientemente grande para alojar el objeto? En este caso se produce la llamada a
una función especial: el manejador de errores de new
o
new-handler. Para ello comprueba si un determinado puntero a
función es nulo, si no lo es, se efectúa la llamada a la función a la que apunta.
El comportamiento por defecto del manejador de errores de new
es disparar
una excepción, asunto del que se tratará en el Volumen 2. Si se piensa usar la
asignación dinámica, conviene al menos reemplazar el manejador de errores de
new
por una función que advierta de la falta de memoria y fuerce la
terminación del programa. De este modo, durante la depuración del programa, se
podrá seguir la pista de lo sucedido. Para la versión final del programa, será
mejor implementar una recuperación de errores más elaborada.
La forma de reemplazar el manejador de new-handler por defecto
consiste en incluir el archivo new.h
y hacer una llamada a la
función set_new_handler()
con la dirección de la función que
se desea instalar:
//: 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 } } ///:~
Listado 13.7. C13/NewHandler.cpp
La función a instalar debe retornar void
y no tomar argumentos. El
bucle while
seguirá pidiendo bloques de int
hasta consumir
la memoria libre disponible, sin hacer nada con ellos. Justo a la siguiente
llamada a new
, no habrá espacio para asignar y se producirá la llamada al
manejador de new
.
Este comportamiento del new-handler está asociado al
operator new()
, de modo que si se sobrecarga
operator new()
(asunto que se trata en la siguiente sección),
no se producirá la llamada al manejador de new
. Si
se desea que se produzca dicha llamada será necesario que lo haga en el
operator new()
que substituya al original.
Por supuesto, es posible escribir manejadores new
más sofisticados,
incluso alguno que intente reclamar los bloques asignados que no se usan
(conocidos habitualmente como recolectores de basura). Pero
este no es un trabajo adecuado para programadores noveles.