Das zweite Problem besteht darin, daß beim zweiten new
-Aufruf
noch einmal Speicher für denselben Pointer beantragt wird. Dies geschieht auch
völlig problemlos. Es existiert jetzt aber kein Pointer mehr, der auf das
zuerst erzeugte Objekt zeigt. Der Speicher wird sinnlos belegt, kann aber nicht
mehr genutzt werden. Hierzu wird der delete
-Operator benötigt. Er
gibt einen zuvor belegten Speicherbereich wieder frei. Der Pointer wird
wieder auf den NULL-Pointer zurückgesetzt.
int* a, *b;
a = new int;
*a = 5;
delete a; // Speicher wird wieder freigegeben
*a = 7; // Fehler: a ist der Null-Pointer
a = new int(7);
b = a; // b zeigt auch auf 5
delete a // Speicher von a freigeben. a ist wieder NULL
*b = 8; // Fehler: Speicherbereich ist schon freigegeben!
Hier taucht das nächste Problem auf. b
und a
zeigen auf
dasselbe Objekt. Durch den delete-Aufruf wird der Speicherbereich wieder
freigegeben und a
auf den NULL-Pointer gesetzt. b
zeigt aber
weiterhin auf den ursprünglichen Speicherbereich. Das Verhalten ist jetzt
undefiniert. Manche Betriebssysteme werden den Zugriff auf freigegebene
Speicherbereiche nicht erlauben, andere erlauben es, es kann aber zu anderen
Ergebnissen führen. Insbesondere wenn der Speicherbereich inzwischen für
ein anderer Objekt reserviert wurde, wird der Inhalt ein anderer sein!
Der Programmierer ist dafür verantwortlich sein Programm so aufzubauen, daß
ein Pointer immer nur auf Speicherbereiche zeigt, die auch einem Objekt
des definierten Typs entsprechen. Auch für die Freigabe des Speichers ist
der Programmierer selber verantwortlich. In kleinen Programmen werden
Speicherlücken nicht weiter auffallen. Wird aber viel Speicherplatz beantragt
wie bei Arrays (siehe folgeden Abschnitt), so kann es schnell dazukommen,
daß nach ein paar new
-Aufrufen der Speicherplatz erschöpft ist.