2010-03-11 11 views
70

Was ist der Unterschied zwischen delete und delete[]-Operatoren in C++?löschen vs löschen [] -Operatoren in C++

+0

Sie könnten diese Frage relevant finden http://stackoverflow.com/questions/1913343/how-could-pairing-new-with-delete-possibly-lead-to-memory-leak-only – sharptooth

+4

Die Probleme mit löschen und delete [] sind ein Grund, warum ich Smart Pointer mag und immer 'vector <>' anstelle eines Arrays benutze. –

+0

http://stackoverflow.com/questions/1553382/pod-freeing-memory-is-delete-equal-to-delete – sbi

Antwort

88

Der Operator delete räumt Speicher frei und ruft den Destruktor für ein einzelnes Objekt auf, das mit new erstellt wurde.

Der Operator delete [] entnimmt Speicher und ruft Destruktoren für ein Array von Objekten auf, die mit new [] erstellt wurden.

Verwendung delete auf einem Zeiger zurückgegeben durch new [] oder delete [] auf einem Zeiger durch new Ergebnisse in undefinierten Verhalten zurückgeführt.

+1

Ich frage mich, wenn Sie löschen auf einem neuen [] Array von primitiven Typen wie int oder char (kein Konstruktor/destruktor) führt zwangsläufig auch zu undefiniertem Verhalten.Es scheint, dass die Array-Größe nirgendwo gespeichert wird, wenn primitive Typen verwendet werden. – thomiel

+12

Wenn der Standard nicht definiert, was passiert, wenn dies gemacht wird, ist es definitionsgemäß "undefiniertes Verhalten", selbst wenn Ihr Compiler deterministisch tut, was Sie tun möchten. Ein anderer Compiler kann etwas völlig anderes tun. –

+0

Ich habe diesen Fehler gemacht, als ich ein Array von C-Strings wie "char ** strArray" hatte. Wenn Sie ein Array wie ich haben, müssen Sie durch das Array iterieren und jedes Element löschen/freigeben und dann das strArray selbst löschen/freigeben. Die Verwendung von "delete []" auf dem Array, das ich habe, funktioniert nicht, da (wie durch die obigen Kommentare und die Antwort darauf hingewiesen wurde) IT CALLS DESTRUCTORS, nicht jeden Slot freigibt. – Katianie

4

Die Betreiber delete und delete [] werden verwendet, die jeweils die Objekte mit new und new[], Rückkehr in den zugewiesenen Speicher links verfügbar in den Speicher-Manager des Compilers erstellt zu zerstören.

mit new erstellt Objekte müssen unbedingt mit delete zerstört werden, und dass die mit new[] erstellt Arrays sollten mit delete[] gelöscht werden.

75

Der Operator delete[] wird zum Löschen von Arrays verwendet. Der Operator delete wird zum Löschen von Nicht-Array-Objekten verwendet. Es ruft die Funktionen operator delete[] bzw. operator delete auf, um den Speicher zu löschen, den das Array oder das Nicht-Array-Objekt belegt hat, nachdem (eventuell) die Destruktoren für die Elemente des Arrays oder das Objekt ohne Array aufgerufen wurden.

Im Folgenden wird die Beziehungen:

typedef int array_type[1]; 

// create and destroy a int[1] 
array_type *a = new array_type; 
delete [] a; 

// create and destroy an int 
int *b = new int; 
delete b; 

// create and destroy an int[1] 
int *c = new int[1]; 
delete[] c; 

// create and destroy an int[1][2] 
int (*d)[2] = new int[1][2]; 
delete [] d; 

Für ein new, die einen Array erzeugt (also entweder die new type[] oder new an ein Array-Typ-Konstrukt angewandt), der Standard für ein operator new[] sieht in dem Elemente des Arrays Typklasse oder im globalen Gültigkeitsbereich und übergibt die angeforderte Speichermenge. Es kann mehr als N * sizeof(ElementType) anfordern, wenn es will (zum Beispiel die Anzahl der Elemente zu speichern, so dass es später beim Löschen weiß, wie viele Destruktoren aufgerufen werden). Wenn die Klasse eine operator new[] deklariert, die zusätzlich zu der Speichermenge eine andere size_t akzeptiert, erhält dieser zweite Parameter die Anzahl der zugeteilten Elemente - er kann diese für jeden gewünschten Zweck verwenden (Debuggen usw.).

Für ein new, das ein Nicht-Array-Objekt erstellt, sucht es nach einem operator new in der Klasse des Elements oder im globalen Bereich. Es übergibt die angeforderte Speichermenge (genau sizeof(T) immer).

Für eine delete[], es untersucht den Element-Klassen-Typ der Arrays und ruft ihre Destruktoren auf. Die verwendete operator delete[]-Funktion ist die in der Klasse des Elementtyps, oder wenn es keine im globalen Bereich gibt.

Für einen delete, wenn der übergebene Zeiger eine Basisklasse des tatsächlichen Objekttyps ist, muss die Basisklasse einen virtuellen Destruktor haben (andernfalls ist das Verhalten nicht definiert). Wenn es sich nicht um eine Basisklasse handelt, wird der Destruktor dieser Klasse aufgerufen und eine in dieser Klasse oder die globale operator delete wird verwendet. Wenn eine Basisklasse übergeben wurde, wird der Destruktor des tatsächlichen Objekttyps aufgerufen, und das in dieser Klasse gefundene wird verwendet, oder, falls keines vorhanden ist, wird ein globales operator delete aufgerufen.Wenn der operator delete in der Klasse einen zweiten Parameter vom Typ size_t hat, erhält er die Anzahl der Elemente, die freigegeben werden sollen.

8

Dies ist die grundlegende Verwendung von zuteilen/DE-zuteilen Muster in C++ malloc/free, neu/löschen, new []/delete []

Wir müssen sie entsprechend verwenden. Aber ich möchte diese besondere Verständnis für den Unterschied zwischen löschen hinzuzufügen und löschen []

1) löschen wird verwendet, Speicher für einzelnes Objekt zugewiesen, um de-zuteilen

2) löschen [] wird verwendet, Speicher für Array von Objekten

Klasse ABC {}

zugeordnet de-zuteilen

ABC * ptr = new ABC [100]

, wenn wir neue sagen [100] .. Compiler können die Informationen darüber, wie viele Objekte erhalten, die zugeordnet werden muss (hier wird es 100) und die rufen Konstruktor für jedes der Objekte erstellt

aber entsprechend, wenn wir einfach ptr für diesen Fall löschen verwenden, Compiler werden nicht wissen, wie viele Objekte, die ptr zu zeigen und Aufruf von destructor am Ende und Speicher löschen für nur 1 Objekt (wobei der Aufruf von Destruktoren und die Zuweisung von 99 verbleibenden Objekten aufgehoben wird). Daher gibt es ein Speicherleck

so müssen wir löschen [] ptr in diesem Fall.

+2

Dies sollte die richtige Antwort sein. Keine der anderen Antworten erwähnen den deutlichen Unterschied: "aber entsprechend, wenn wir einfach delete ptr für diesen Fall verwenden, wird der Compiler nicht wissen, wie viele Objekte, auf die ptr zeigt, am Ende Destruktor aufrufen und Speicher für nur 1 Objekt löschen" –

+0

Wie erreichen wir dasselbe in C? –

-1

delete wird für einen einzelnen Zeiger verwendet und delete[] wird zum Löschen eines Arrays über einen Zeiger verwendet. This könnte Ihnen helfen, besser zu verstehen.

0

Wenn ich diese Frage stellte, war meine wirkliche Frage: "Gibt es einen Unterschied zwischen den beiden? Muss die Laufzeit nicht Informationen über die Array-Größe halten, und wird nicht in der Lage zu sagen, welche wir bedeuten?" Diese Frage erscheint nicht in "verwandten Fragen", also nur um denen wie mir zu helfen, hier ist die Antwort darauf: "why do we even need the delete[] operator?"

0

Nun .. vielleicht denke ich, es ist nur für explizite. Der Operator delete und der Operator delete [] wird unterschieden, aber der delete-Operator kann auch das Array freigeben.

test* a = new test[100]; 
delete a; 

Und bereits überprüft haben diesen Code keine Memeory Leck.