Namensräume
Varianten
Aktionen

delete-Ausdruck

Von cppreference.com
< cpp‎ | Sprache
 
 
C++ Sprache
Allgemeine Themen
Kontrollfluss
Bedingte Ausführungsaussagen
if
Iterationsanweisungen (Schleifen)
for
Bereichs-for (C++11)
Sprunganweisungen
Funktionen
Funktionsdeklaration
Lambda-Funktionsausdruck
inline-Spezifizierer
Dynamische Ausnahmespezifikationen (bis C++17*)
noexcept-Spezifizierer (C++11)
Ausnahmen
Namensräume
Typen
Spezifizierer
const/volatile
decltype (C++11)
auto (C++11)
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Speicherdauer-Spezifizierer
Initialisierung
Ausdrücke
Alternative Darstellungen
Literale
Boolesch - Ganzzahl - Gleitkommazahl
Zeichen - String - nullptr (C++11)
Benutzerdefinierte (C++11)
Dienstprogramme
Attribute (C++11)
Typen
typedef-Deklaration
Typalias-Deklaration (C++11)
Umwandlungen
Speicherzuweisung
delete-Ausdruck
Klassen
Klassenspezifische Funktionseigenschaften
explicit (C++11)
static

Spezielle Member-Funktionen
Templates
Sonstiges
 
 

Zerstört durch den new-Ausdruck zuvor zugewiesene Objekte und gibt den belegten Speicherbereich frei.

Inhalt

[edit] Syntax

::(optional) delete   Ausdruck (1)
::(optional) delete[] Ausdruck (2)
expression - einer der folgenden
1) Zerstört ein einzelnes Nicht-Array-Objekt, das durch einen new-Ausdruck erzeugt wurde.
2) Zerstört ein Array, das durch einen new[]-Ausdruck erzeugt wurde.

[edit] Erläuterung

Gegeben sei der durch Ausdruck ausgewertete Zeiger (nach möglichen Konvertierungen) als ptr.

1) ptr muss einer der folgenden sein:
  • ein Nullzeiger,
  • ein Zeiger auf ein Nicht-Array-Objekt, das durch einen new-Ausdruck erzeugt wurde, oder
  • ein Zeiger auf ein Basis-Subobjekt eines Nicht-Array-Objekts, das durch einen new-Ausdruck erzeugt wurde.
Der zeigende Typ von ptr muss ähnlich dem Typ des Objekts (oder eines Basis-Subobjekts) sein. Wenn ptr etwas anderes ist, einschließlich wenn es ein Zeiger ist, der durch die Array-Form des new-Ausdrucks erhalten wurde, ist das Verhalten undefiniert.
2) ptr muss ein Nullzeiger oder ein Zeiger sein, dessen Wert zuvor durch eine Array-Form des new-Ausdrucks erhalten wurde, deren Allokationsfunktion keine nicht-allozierende Form war (d. h. Überladung (10)).
Der zeigende Typ von ptr muss ähnlich dem Elementtyp des Array-Objekts sein. Wenn ptr etwas anderes ist, einschließlich wenn es ein Zeiger ist, der durch die Nicht-Array-Form des new-Ausdrucks erhalten wurde, ist das Verhalten undefiniert.

Das Ergebnis des delete-Ausdrucks hat immer den Typ void.

Wenn das zu löschende Objekt zum Zeitpunkt der Löschung einen unvollständigen Klassentyp hat, und die vollständige Klasse einen nicht-trivialen Destruktor oder eine Deallokationsfunktion hat, ist das Verhalten undefiniert(bis C++26)ist das Programm schlecht formuliert(seit C++26).

Wenn ptr kein Nullzeiger istund die Deallokationsfunktion kein löschender delete ist(seit C++20), ruft der delete-Ausdruck den Destruktor (falls vorhanden) für das zu zerstörende Objekt auf, oder für jedes Element des zu zerstörenden Arrays (beginnend beim letzten Element bis zum ersten). Der Destruktor muss von dem Punkt an, an dem der delete-Ausdruck erscheint, zugänglich sein.

Danach ruft der delete-Ausdruck, unabhängig davon, ob ein Destruktor eine Ausnahme ausgelöst hat, die Deallokationsfunktion auf: entweder operator delete (erste Version) oder operator delete[] (zweite Version), es sei denn, der passende new-Ausdruck wurde mit einem anderen new-Ausdruck kombiniert(seit C++14).

Der Name der Deallokationsfunktion wird im Gültigkeitsbereich des dynamischen Typs des von ptr gezeigten Objekts nachgeschlagen, was bedeutet, dass klassenspezifische Deallokationsfunktionen, falls vorhanden, vor den globalen gefunden werden. Wenn :: im delete-Ausdruck vorhanden ist, wird durch diese Suche nur der globale Namensraum untersucht. In jedem Fall werden alle Deklarationen, die keine üblichen Deallokationsfunktionen sind, verworfen.

Wenn eine Deallokationsfunktion gefunden wird, wird die aufzurufende Funktion wie folgt ausgewählt (siehe Deallokationsfunktion für eine detailliertere Beschreibung dieser Funktionen und ihrer Auswirkungen)

  • Wenn mindestens eine der Deallokationsfunktionen ein löschendes delete ist, werden alle nicht-löschenden deletes ignoriert.
(seit C++20)
  • Wenn die Ausrichtungsanforderung des Typs __STDCPP_DEFAULT_NEW_ALIGNMENT__ überschreitet, werden ausrichtungsbewusste Deallokationsfunktionen (mit einem Parameter vom Typ std::align_val_t) bevorzugt. Für andere Typen werden die nicht-ausrichtungsbewussten Deallokationsfunktionen (ohne Parameter vom Typ std::align_val_t) bevorzugt.
  • Wenn mehr als eine bevorzugte Funktion gefunden wird, werden im nächsten Schritt nur bevorzugte Funktionen berücksichtigt.
  • Wenn keine bevorzugten Funktionen gefunden werden, werden die nicht-bevorzugten im nächsten Schritt berücksichtigt.
  • Wenn nur noch eine Funktion übrig ist, wird diese ausgewählt.
(seit C++17)
  • Wenn die gefundenen Deallokationsfunktionen klassenspezifisch sind, wird eine klassenspezifische Deallokationsfunktion ohne Größeninformation (ohne Parameter vom Typ std::size_t) gegenüber einer klassenspezifischen Deallokationsfunktion mit Größeninformation (mit Parameter vom Typ std::size_t) bevorzugt.
  • Andernfalls hat die Suche den globalen Gültigkeitsbereich erreicht, und
  • Wenn der Typ vollständig ist und wenn für die Array-Form des Operanden der Operand ein Zeiger auf einen Klassentyp mit einem nicht-trivialen Destruktor oder ein (möglicherweise mehrdimensionales) Array davon ist, wird die globale, größeninformierte globale Funktion (mit einem Parameter vom Typ std::size_t) ausgewählt.
  • Andernfalls ist es nicht spezifiziert, ob die globale, größeninformierte Deallokationsfunktion (mit einem Parameter vom Typ std::size_t) oder die globale, größenuninformierte Deallokationsfunktion (ohne Parameter vom Typ std::size_t) ausgewählt wird.
(seit C++14)

Die ausgewählte Deallokationsfunktion muss von dem Punkt an, an dem der delete-Ausdruck erscheint, zugänglich sein, es sei denn, die Deallokationsfunktion wird an der Punktdefinition des dynamischen Typs des virtuellen Destruktors ausgewählt.

Der Zeiger auf den wiederzugewinnenden Speicherblock wird als erstes Argument an die Deallokationsfunktion übergeben, die durch den obigen Prozess ausgewählt wurde. Die Größe des Blocks wird als optionales std::size_t-Argument übergeben. Die Ausrichtungsanforderung wird als optionales std::align_val_t-Argument übergeben.(seit C++17)

Wenn ptr ein Nullzeigerwert ist, werden keine Destruktoren aufgerufen, und die Deallokationsfunktion kann aufgerufen werden oder auch nicht (es ist nicht spezifiziert), aber die Standard-Deallokationsfunktionen garantieren, dass sie nichts tun, wenn sie mit einem Nullzeiger aufgerufen werden.

Wenn ptr ein Zeiger auf ein Basisklassen-Subobjekt des mit new alloziierten Objekts ist, muss der Destruktor der Basisklasse virtuell sein, andernfalls ist das Verhalten undefiniert.

[edit] Anmerkungen

Ein Zeiger auf void kann nicht gelöscht werden, da es kein Zeiger auf einen Objekttyp ist.

Da ein Paar Klammern nach dem Schlüsselwort delete immer als die Array-Form eines delete-Ausdrucks interpretiert wird, muss ein Lambda-Ausdruck mit leerer Capture-Liste unmittelbar nach delete in Klammern gesetzt werden.

// delete []{ return new int; }(); // parse error
delete ([]{ return new int; })();  // OK
(seit C++11)

[edit] Schlüsselwörter

delete

[edit] Fehlerberichte

Die folgenden Verhaltensändernden Fehlerberichte wurden rückwirkend auf zuvor veröffentlichte C++-Standards angewendet.

DR angewendet auf Verhalten wie veröffentlicht Korrigiertes Verhalten
CWG 288 C++98 für die erste Form wurde der statische Typ des
Operanden mit seinem dynamischen Typ verglichen
vergleiche den statischen Typ des Objekts
das gelöscht werden soll, mit seinem dynamischen Typ
CWG 353 C++98 ob die Deallokationsfunktion aufgerufen wird, wenn
der Destruktor eine Ausnahme auslöst, war nicht spezifiziert
wird immer aufgerufen
CWG 599 C++98 die erste Form konnte einen Nullzeiger von
jedem Typ, einschließlich Funktionszeigern,
außer Zeigern auf Objekttypen, annehmen
alle anderen Zeigertypen werden abgelehnt
CWG 1642 C++98 Ausdruck könnte ein Zeiger-Lvalue sein nicht erlaubt
CWG 2474 C++98 das Löschen eines Zeigers auf ein Objekt eines ähnlichen, aber
anderen Typs führte zu undefiniertem Verhalten
wurde wohlformuliert
CWG 2624 C++98 von nicht-allozierenden
operator new[] erhaltene Zeiger konnten an delete[] übergeben werden
verboten
CWG 2758 C++98 es war unklar, wie die Zugriffskontrolle für
die Deallokationsfunktion und den Destruktor gehandhabt wurde
wurde klargestellt

[edit] Siehe auch