Frage zu delete[]
-
Hi,
wenn du mit new[] ein Feld anlegst wird die Feldgroesse mit gespeichert.
Hier kurz ein Auszug dazu aus "Die C++-Programmiersprache" von Stroustrup.Um von new belegten Speicher freizugeben, muessen new und new[] die Groesse des angelegten Objektes ermitteln koennen. Dies bedingt, dass ein mit der Standardimplementierung von new angelegtes Objekt etwas mehr Speicher als ein statisches Objekt belegt. Ueblicherweise wird ein Wort benutzt, um die Groesse des Objektes abzulegen.
-
Ok, vielen Dank!
-
Lügt mein Buch wenn es behauptet, dass es völlig egal ist ob man Arrays mit
delete[] array;oder
delete array;freigibt?
-
Ja das ist Schwachsinn und führt mit ziemlicher Sicherheit zu Memory Leaks
-
mahe schrieb:
Lügt mein Buch wenn es behauptet, dass es völlig egal ist ob man Arrays mit
delete[] array;oder
delete array;freigibt?
Wie heißt denn das Buch? Das sollte man ja möglichst meiden (bzw. nicht weiterempfehlen).
-
int* arr = new int[10]; delete arr;ist schlichtweg undefiniertes verhalten und auchnicht, wie man vllt denken könnte, das das 1. Element aus dem Array gelöscht wird. Undefiniert.
int* arr = new int(0); delete [] arr;Auch hier undefiniertes Verhalten.
Laut Standard muss Speicher, der mit new angelegt wurde, mit delete gelöscht werden und Speicher, der mit new[] angelegt wurde, mit delete[] gelöscht werden.
-
was ich auch ganz interessant finde:
der Standard garantiert das delete keine Pointer auf 0 loescht. Also kein ueberprufen alaif( pointer != 0 ) delete pointer;
-
Ich denke mal, dass nicht das Freigeben des Speichers das Problem beim Vertauschen von delete und delete[] ist, sondern dass bei ersterem nur der Destruktor des ersten Elements aufgerufen wird und nicht von allen Elementen.
-
Stefan schrieb:
Ich denke mal, dass nicht das Freigeben des Speichers das Problem beim Vertauschen von delete und delete[] ist, sondern dass bei ersterem nur der Destruktor des ersten Elements aufgerufen wird und nicht von allen Elementen.
Der Standard überlässt es gänzlich der Implementierung, wie diese Mechanismen arbeiten. Folglich sind verschiedene Verhaltensweisen denkbar. Konsequenterweise lässt der Standard dies völlig undefiniert - und das bedeutet für den Programmierer, dass man diese Problematik immer zu vermeiden hat. Gewinnen kann man hier ohnehin nichts und das spezielle Verhalten eines Compilers ist höchtens beim Debuggen von Interesse.
-
Stefan schrieb:
Ich denke mal, dass nicht das Freigeben des Speichers das Problem beim Vertauschen von delete und delete[] ist, sondern dass bei ersterem nur der Destruktor des ersten Elements aufgerufen wird und nicht von allen Elementen.
Na, Meyers schreibt hierzu so schon (sinngemäß): „Es ist undefiniert. Das heißt, der Compiler könnte dafür auch Code generieren, der jedes vierte Byte auf der Festplatte überschreibt.“

Kohma schrieb:
was ich auch ganz interessant finde:
der Standard garantiert das delete keine Pointer auf 0 loescht. Also kein ueberprufen alaif( pointer != 0 ) delete pointer;Das stimmt zwar, allerdings gibt es diese Anforderung nicht für eigene Überladungen von 'operator delete'. D.h. es wäre durchaus eine eigene Version denkbar, die *keinen* Spezialfall für einen Nullzeiger macht, sodass obiger Prüfcode sehr wohl nötig werden kann (wobei ich nicht denke, dass es einen sinnvollen Anwendungsfall für solch eine Überladung gibt).
-
Konrad Rudolph schrieb:
Das stimmt zwar, allerdings gibt es diese Anforderung nicht für eigene Überladungen von 'operator delete'.
Das stimmt zwar, allerdings gibt es große Steine mit denen man dem Programmierer den Schädel zertrümmern kann, wenn sein delete diese Anforderung nicht erfüllt.
-
Lol,
ihr habt ja recht! Wenn ich sowas schreibe sollte ich auch soweit denken und auf sowas hinweisen

-
Konrad Rudolph schrieb:
Kohma schrieb:
was ich auch ganz interessant finde:
der Standard garantiert das delete keine Pointer auf 0 loescht. Also kein ueberprufen alaif( pointer != 0 ) delete pointer;Das stimmt zwar, allerdings gibt es diese Anforderung nicht für eigene Überladungen von 'operator delete'. D.h. es wäre durchaus eine eigene Version denkbar, die *keinen* Spezialfall für einen Nullzeiger macht, sodass obiger Prüfcode sehr wohl nötig werden kann (wobei ich nicht denke, dass es einen sinnvollen Anwendungsfall für solch eine Überladung gibt).
Es gibt da diesen merkwürdigen Satz in 5.3.5/2
In either alternative, if the value of the operand of delete is the null pointer the operation has no effect.
Gemeint sind die Alternativen von non-Array- und Array-delete. iirc wird die Formulierung im nächsten Standard verbessert werden. Die Anwendung des delete-Operators soll stets möglich sein - Das ist jedenfalls die Absicht des Standardkomitees unabhängig von der etwas mehrdeutigen Formulierung (man beachte: 5.3.5/7: The delete-expression will call a deallocation function (3.7.3.2). Der Aufruf einer potentiell durch den Nutzer bereitgestellten Funktion wird durch "has no effect" kaum adäquat beschrieben. Oder soll dieser Satz bei Null-Pointern nicht gelten? Dann hätte man den Abschnitt systematisch anders aufbauen sollen.).
Ich habe in der Vergangenheit etwas anderes geschrieben - aber 80% ist sowieso immer falsch. Nachdenken ist ohnehin wichtiger als die Produktion zitierfähigen Materials.
-
jehova schrieb:
Konrad Rudolph schrieb:
Das stimmt zwar, allerdings gibt es diese Anforderung nicht für eigene Überladungen von 'operator delete'.
Das stimmt zwar, allerdings gibt es große Steine mit denen man dem Programmierer den Schädel zertrümmern kann, wenn sein delete diese Anforderung nicht erfüllt.
Gut geantwortet.
