Wenn nicht genügend Speicher zur Verfügung steht, liefert
new 0
zurück. Auch bei kleineren Speicheranfragen kann das jederzeit passieren.
Deshalb sollte jede Zuweisung mit new mit einer
entsprechenden Abfrage und Fehlerbehandlung verbunden sein.
Das ist allerdings meistens nicht nur lästig für den Programmierer,
bei komplizierteren Strukturen kann es einen Quelltext schnell sehr
unübersichtlich machen.
Wenn keine ausgefeilte Fehlerbehandlung erforderlich ist, ist es oft
ausreichend, mit sogenannten new-Handlern zu arbeiten. Das sind
selbstgeschriebene Routinen, die bei Speichermangel automatisch von
new aus angesprungen werden.
Problematisch ist natürlich, daß innerhalb dieser Routine nicht
bekannt sein kann, an welcher Stelle im Programm der new-Aufruf liegt. Die
Fehlerbehandlung beschränkt sich so meistens auf eine bedauernde
Fehlermeldung und den Programmabbruch -- immerhin besser als ein späterer
Absturz durch einen nicht gültigen Pointer.
Eine eigene Handler-Routine könnte also wie folgt aussehen:
- void my_error_handler()
{
cerr << "Ich bedaure außerordentlich, Ihnen mitteilen zu müssen, \n";
cerr << "daß nicht mehr genügend Speicher im System zur Verfügung\n";
cerr << "steht. Ciao!\n";
exit(0);
}
Die Funktion aus der Standard-Bibliothek, mit der man den eigenen Handler
bekanntgibt, ist in new.h deklariert:
- extern void (*set_new_handler (void(*)()))();
Ein Pointer auf die zuvor aktuelle Routine wird von dieser Funktion
zurückgeliefert, so daß sie später wieder restauriert werden
kann.
Es folgt ein Testprogramm für unsere Routine:
- void main(void)
{
set_new_handler(my_error_handler);
char *glutton=new char[2147483647];
}
Je nach Programm kann es auch Möglichkeiten geben,
die Situation ohne Programmabbruch zu bestehen.
Eventuell kann man anderen Speicher freigeben, z.B. wenn er
später leicht wieder restauriert (geladen, neuberechnet) werden kann.
Dann kann die Handler-Routine das erledigen und ohne exit
zurückkehren. new versucht dann automatisch erneut,
genügend Speicher zu besorgen.
So kann man allerdings auch leicht in eine endlose Folge von Aufrufen
des Handlers geraten. Dieser sollte wirklich nur dann zu new
zurückkehren, wenn genügend viel Speicher freigemacht werden konnte.
Im Zusammenhang mit Klassen gibt es den Vorteil, daß man den
Operator new (für jede Klasse getrennt) überladen und
dort jeweils einen speziellen Handler anwählen kann (dazu später).
Noch besser ist es natürlich, wenn von dort aus eine
Exception-Behandlung angestoßen wird (dazu noch später).