Wenn wir ein Objekt der Größe 1 wie folgt zuordnen
%Vor% Sollen wir das Objekt mit operator delete[]
oder operator delete
löschen?
Der Grund, warum ich besorgt bin, ist, wenn der Compiler schlau genug wäre, die Anweisung als einzelne Elementzuweisung int *arr = new int
zu konvertieren, was dazu führen würde, dass operator delete[]
UB aufgerufen wird.
Benutzerfall:
Ich habe einen Zeiger, mit dem ich auf verschiedene Arten enden würde, möchte ihn aber schließlich löschen lassen. Ich frage mich also, ob ich für die Einzelelement-Zuweisung% ce_de% konsistent und sicher verwenden kann, wenn ich konsequent int *arr = new int[1]
Hinweis
Können Sie mich bitte zurück zu den Standards bringen, um Ihre Antwort zu unterstützen?
Sie müssen delete[]
und nicht delete
verwenden. Der Compiler darf new int[1]
nicht in new int
ändern.
(Da int
ein POD-Typ ist, ist es durchaus möglich, dass new int
und new int[1]
genau dasselbe unter den Deckblättern tun, aber wenn dies der Fall ist, dann delete[]
on und int*
und delete
auf einem int*
macht auch genau das gleiche.)
ISO / IEC 14882: 2011 5.3.5 [expr.delete] / 2:
In der ersten Alternative ( delete object ) kann der Wert des Operanden
delete
ein Nullzeigerwert sein, ein Zeiger auf ein Nicht-Array-Objekt, das von einem vorherigen erstellt wurde new-expression oder ein Zeiger auf ein Unterobjekt (1.8), das eine Basisklasse eines solchen Objekts darstellt (Abschnitt 10). Wenn nicht, ist das Verhalten nicht definiert.
As int[1]
ist ein Array-Objekt. Wenn Sie versuchen, es mit delete
und nicht mit delete[]
zu löschen, ist das Verhalten nicht definiert.
Die Regel ist ziemlich einfach:
new
mit delete
new[]
mit delete[]
aus
Andernfalls erhalten Sie undefiniertes Verhalten .
Es gibt keine Ausnahmen; even new[1]
muss mit einem delete[]
ausgeglichen werden, und new[0]
muss gelöscht werden, da der Compiler immer noch Speicherplatz reservieren kann.
Sollen wir das Objekt mit dem Operator
delete[]
oderoperator delete
löschen?
operator delete[]
. Sie haben ein Array von int
s zugewiesen, sodass es keine andere Möglichkeit gibt, die Zuordnung korrekt aufzuheben. Die Verwendung von operator delete
würde zu undefiniertem Verhalten führen.
Da Sie []
für die Zuweisung verwenden, müssen Sie auch []
für delete
verwenden.
Die von neuen Ausdrücken erzeugten Objekte (Objekte mit dynamischem Speicher Dauer) bestehen bleiben, bis der vom neuen Ausdruck zurückgegebene Zeiger Wird in einem übereinstimmenden Löschausdruck verwendet.
Sie sollten also delete[]
für die Freigabe des Speichers verwenden, sonst erhalten Sie undefiniertes Verhalten.
Und (incase) , wenn der Compiler schlau genug ist, um int * arr = new int[1]
als int
zu nehmen, muss er intelligent genug sein, um delete[] arr
an arr
als delete arr
zu übernehmen. Allerdings gibt es für delete
nichts, um zwischen arr
von int*arr = new int[1]
und int*arr = new int
zu unterscheiden. Die []
in delete
wird dies anzeigen.
Nein, es ist nicht sicher, es kann zu einigen unerwünschten Situationen führen.
Zum Beispiel ist es in einem Speicher möglich, einige Daten ( int/char/float
...) neben dem Ort zu haben, auf den der Zeiger zeigt. Wenn Sie zu diesem Zeitpunkt delete []
verwendet haben, versucht es möglicherweise auch, diese Daten zu löschen, wenn es sich um eine Ganzzahl handelt. Bei anderen Datentypen führt dies zu unerwarteten Fehlern.
Beispiel:
Es besteht die Möglichkeit, dass die Variablen c
und a
neben dem Ort gespeichert werden, auf den der Zeiger ptr
zeigt, wenn a
daneben gespeichert ist, dann löscht er auch " a
" , wenn die anderen Datentypen vorhanden sind, führt zu unerwarteten Laufzeit-Ergebnissen.
Es wird daher empfohlen, delete[]
nur zum Löschen von Speicher zu verwenden, der mit dem neuen Datentyp []
.Hope zugewiesen wurde. Dies ist nützlich.
Tags und Links c++