Frage

In C ++, ich verstehe, dass die delete Operator, wenn sie mit einem Array verwendet, ‚zerstört‘ es, die Befreiung der Speicher es verwendet. Aber was passiert, wenn dies geschehen ist?

dachte ich mein Programm würde nur den relevanten Teil des Haufens markiert zur Weiterverwendung freigegeben wird, und weiter auf.

Aber ich merkte, dass auch das erste Element des Arrays ist auf null, während die anderen Elemente unverändert bleiben. Welchem ??Zweck diese dienen?

int * nums = new int[3];
nums[0] = 1;
nums[1] = 2;

cout << "nums[0]: " << *nums << endl;
cout << "nums[1]: " << *(nums+1) << endl;

delete [] nums;

cout << "nums[0]: " << *nums << endl;
cout << "nums[1]: " << *(nums+1) << endl;
War es hilfreich?

Lösung

Zwei Dinge passieren, wenn delete[] genannt wird:

  1. Falls die Anordnung von einem Typ ist, der ein nicht-triviale destructor hat, der Destruktor für jedes der Elemente in der Anordnung, in umgekehrter Reihenfolge aufgerufen
  2. Der Speicher durch das Feld belegt ist freigegeben

Zugriff auf den Speicher, dass das Array belegt nach delete Ergebnisse in undefinierten Verhalten Aufruf (das heißt, alles, was passieren könnte - die Daten noch da sein könnte, oder Ihr Programm könnte abstürzen, wenn Sie versuchen, es zu lesen, oder etwas anderes viel schlimmer passieren könnte).

Andere Tipps

Die Gründe dafür NULL sind auf dem Heap Implementierung auf.

Einige mögliche Gründe sind, dass sie den Raum nutzt für Freiraum Tracking es ist. Es könnte, sie als einen Zeiger auf den nächsten freien Block sein. Es könnte mit ihm sein, die Größe des freien Blocks aufzuzeichnen. Es könnte in einigen Seriennummer für neue / löschen Debug-Tracking schreiben.

Es könnte nur NULL schreiben, weil es wie es sich anfühlt.

Jedes Mal, wenn jemand int* nums = new int[3] sagt, wird das Laufzeitsystem benötigt, um die Anzahl der Objekte zu speichern, 3, in einem Ort, der nur den Zeiger zu wissen, abgerufen werden kann, nums. Der Compiler kann jede Technik verwenden, es benutzen will, aber es gibt zwei beliebtesten.

Der Code von nums = new int[3] erzeugt könnte die Anzahl 3 in einem statischen assoziativen Array speichern, wo der Zeiger nums als Suchschlüssel verwendet wird, und die Anzahl 3 ist der zugehörige Wert. Der Code, erzeugt durch delete[] nums würde den Zeiger in die assoziative Array nachzuschlagen, würde die zugeordnete size_t extrahieren, dann würde der Eintrag aus der assoziative Array entfernen.

Der Code von nums = new int[3] erzeugt könnte eine zusätzliche sizeof (size_t) zuzuteilen Bytes des Speichers (möglicherweise plus einige Ausrichtungs Bytes) und setzt den Wert 3 kurz vor dem ersten int Objekt. Dann delete[] nums würde 3 durch einen Blick auf dem festen Offset vor dem ersten int Objekt findet (die vor *num) zur Verfügung und würde die Speicher ab Beginn der Zuweisung freizugeben (das heißt, der Block des Speichers beginnt die vor *nums Offset fest) .

Keine Technik ist perfekt. Hier sind einige der Vor- und Nachteile.

Die assoziative Array-Technik ist langsamer, aber sicherer: wenn jemand die [] vergisst, wenn eine Reihe von Dingen, das Aufheben von Zuweisungen, (a) der Eintrag in dem assoziativen Array wäre ein Leck, und (b) nur das erste Objekt in der Anordnung würde werden zerstört. Dies kann oder kann nicht ein ernstes Problem sein, aber zumindest ist es vielleicht nicht die Anwendung zum Absturz bringen.

Die Überlastung Technik ist schneller, aber gefährlicher: Wenn jemand sagt delete nums, wo sie sollten delete[] nums gesagt haben, die Adresse, die Betreiber delete(void* nums) geben würde keine gültige Heapzuordnung-es sei zumindest sizeof(size_t) Bytes nach einer gültigen Heap Zuweisung. Dies würde der Haufen wahrscheinlich beschädigt. - C ++ FAQs

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top