Kann ich 'operator delete []' für eine einzelne Element-Array-Zuweisung verwenden?

7

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]

verwende

Hinweis

Können Sie mich bitte zurück zu den Standards bringen, um Ihre Antwort zu unterstützen?

    
Abhijit 12.07.2013, 07:23
quelle

6 Antworten

13

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.

    
Charles Bailey 12.07.2013, 07:25
quelle
6

Die Regel ist ziemlich einfach:

  1. gleicht immer new mit delete
  2. aus
  3. gleicht immer 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.

    
Bathsheba 12.07.2013 07:27
quelle
2
  

Sollen wir das Objekt mit dem Operator delete[] oder operator 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.

    
user529758 12.07.2013 07:26
quelle
2

Sie müssen delete[] verwenden.

C ++ 11 5.3.5 Löschen

  

:: opt cast-expression löschen

     

:: opt delete [] Cast-Ausdruck

     

Die erste Alternative ist für Nicht-Array-Objekte und die zweite für Arrays.

Ein Array, das ein Element enthält, ist immer noch ein Array.

    
Yu Hao 12.07.2013 07:27
quelle
1
%Vor%

Da Sie [] für die Zuweisung verwenden, müssen Sie auch [] für delete verwenden.

  

Speicherlecks

     

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.

    
Suvarna Pattayil 12.07.2013 07:44
quelle
0

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:

%Vor%

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.

    
Mahesh 12.07.2013 10:07
quelle

Tags und Links