Namespaces
Variants

delete expression

From cppreference.net
C++ language
General topics
Flow control
Conditional execution statements
Iteration statements (loops)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications ( until C++17* )
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Storage duration specifiers
Initialization
Expressions
Alternative representations
Literals
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Utilities
Attributes (C++11)
Types
typedef declaration
Type alias declaration (C++11)
Casts
Memory allocation
delete expression
Classes
Class-specific function properties
Special member functions
Templates
Miscellaneous

Détruit l'objet (ou les objets) précédemment alloué(s) par l' expression new et libère la zone mémoire obtenue.

Table des matières

Syntaxe

:: (optionnel) delete expression (1)
:: (optionnel) delete[] expression (2)
expression - l'un des éléments suivants :
1) Détruit un objet non-tableau créé par une new-expression .
2) Détruit un tableau créé par une new[]-expression .

Explication

Étant donné le pointeur évalué à partir de expression (après conversions possibles) comme ptr .

1) ptr doit être l'un des éléments suivants
  • un pointeur nul,
  • un pointeur vers un objet non-tableau créé par une new-expression , ou
  • un pointeur vers un sous-objet de base d'un objet non-tableau créé par une new-expression .
Le type pointé par ptr doit être similaire au type de l'objet (ou d'un sous-objet de base). Si ptr est autre chose, y compris s'il s'agit d'un pointeur obtenu par la forme tableau de new-expression , le comportement est indéfini .
2) ptr doit être un pointeur nul ou un pointeur dont la valeur a été précédemment obtenue par une forme tableau de new-expression dont la fonction d'allocation n'était pas une forme non-allouante (c'est-à-dire la surcharge (10) ).
Le type pointé par ptr doit être similaire au type d'élément de l'objet tableau. Si ptr est autre chose, y compris s'il s'agit d'un pointeur obtenu par la forme non-tableau de new-expression , le comportement est indéfini .

Le résultat de l'expression delete a toujours le type void .

Si l'objet en cours de suppression a un type de classe incomplet au moment de la suppression, et que la classe complète a un destructeur non trivial ou une fonction de désallocation, le comportement est indéfini (jusqu'à C++26) le programme est mal formé (depuis C++26) .

Si ptr n'est pas un pointeur nul et que la fonction de désallocation n'est pas un delete destructeur (depuis C++20) , l'expression delete invoque le destructeur (s'il existe) pour l'objet qui est détruit, ou pour chaque élément du tableau en cours de destruction (en procédant du dernier élément au premier élément du tableau). Le destructeur doit être accessible depuis l'endroit où l'expression delete apparaît.

Après cela, qu'une exception ait été levée ou non par un destructeur, l'expression delete invoque la fonction de désallocation : soit operator delete (première version) soit operator delete [ ] (deuxième version) , sauf si l'expression new correspondante était combinée avec une autre expression new (depuis C++14) .

Le nom de la fonction de désallocation est recherché dans la portée du type dynamique de l'objet pointé par ptr , ce qui signifie que les fonctions de désallocation spécifiques à la classe, si présentes, sont trouvées avant les fonctions globales. Si :: est présent dans l'expression delete, seul l'espace de noms global est examiné par cette recherche. Dans tous les cas, toute déclaration autre que celle des fonctions de désallocation usuelles est écartée.

Si une fonction de désallocation est trouvée, la fonction à appeler est sélectionnée comme suit (voir fonction de désallocation pour une description plus détaillée de ces fonctions et de leurs effets) :

  • Si au moins une des fonctions de désallocation est un delete destructeur, tous les delete non destructeurs sont ignorés.
(depuis C++20)
  • Si l'exigence d'alignement du type dépasse __STDCPP_DEFAULT_NEW_ALIGNMENT__ , les fonctions de désallocation sensibles à l'alignement (avec un paramètre de type std::align_val_t ) sont préférées. Pour les autres types, les fonctions de désallocation non sensibles à l'alignement (sans paramètre de type std::align_val_t ) sont préférées.
  • Si plus d'une fonction préférée est trouvée, seules les fonctions préférées sont considérées à l'étape suivante.
  • Si aucune fonction préférée n'est trouvée, les fonctions non préférées sont considérées à l'étape suivante.
  • Si une seule fonction reste, cette fonction est sélectionnée.
(depuis C++17)
  • Si les fonctions de désallocation trouvées sont spécifiques à la classe, la fonction de désallocation spécifique à la classe non sensible à la taille (sans paramètre de type std::size_t ) est préférée à la fonction de désallocation spécifique à la classe sensible à la taille (avec un paramètre de type std::size_t ).
  • Sinon, la recherche atteint la portée globale, et :
  • Si le type est complet et si, pour la forme tableau uniquement, l'opérande est un pointeur vers un type classe avec un destructeur non trivial ou un tableau (éventuellement multidimensionnel) de celui-ci, la fonction globale tenant compte de la taille (avec un paramètre de type std::size_t ) est sélectionnée.
  • Sinon, il n'est pas spécifié si la fonction globale de désallocation tenant compte de la taille (avec un paramètre de type std::size_t ) ou la fonction globale de désallocation ne tenant pas compte de la taille (sans paramètre de type std::size_t ) est sélectionnée.
(depuis C++14)

La fonction de désallocation sélectionnée doit être accessible depuis l'endroit où l'expression delete apparaît, sauf si la fonction de désallocation est sélectionnée au point de définition du type dynamique ’s destructeur virtuel .

Le pointeur vers le bloc de stockage à libérer est passé à la fonction de désallocation qui a été sélectionnée par le processus ci-dessus comme premier argument. La taille du bloc est passée comme argument optionnel std::size_t . L'exigence d'alignement est passée comme argument optionnel std::align_val_t . (depuis C++17)

Si ptr est une valeur de pointeur nul, aucun destructeur n'est appelé, et la fonction de désallocation peut ou non être appelée (c'est non spécifié), mais les fonctions de désallocation par défaut sont garanties de ne rien faire lorsqu'elles reçoivent un pointeur nul.

Si ptr est un pointeur vers un sous-objet de classe de base de l'objet qui a été alloué avec new , le destructeur de la classe de base doit être virtual , sinon le comportement est indéfini.

Notes

Un pointeur vers void ne peut pas être supprimé car il ne s'agit pas d'un pointeur vers un type objet.

Étant donné qu'une paire de crochets suivant le mot-clé delete est toujours interprétée comme la forme tableau d'une expression de suppression, une expression lambda avec une liste de capture vide immédiatement après delete doit être entourée de parenthèses.

// delete []{ return new int; }(); // erreur d'analyse
delete ([]{ return new int; })();  // OK
(depuis C++11)

Mots-clés

delete

Rapports de défauts

Les rapports de défauts modifiant le comportement suivants ont été appliqués rétroactivement aux normes C++ précédemment publiées.

DR Applicable à Comportement publié Comportement corrigé
CWG 288 C++98 pour la première forme, le type statique de
l'opérande était comparé à son type dynamique
comparer le type statique de l'objet
à supprimer avec son type dynamique
CWG 353 C++98 si la fonction de désallocation serait invoquée lorsque
le destructeur lève une exception n'était pas spécifié
toujours invoquée
CWG 599 C++98 la première forme pouvait accepter un pointeur nul de
n'importe quel type, y compris les pointeurs de fonction
à l'exception des pointeurs vers types objets,
tous les autres types de pointeurs sont rejetés
CWG 1642 C++98 expression pouvait être une lvalue pointeur non autorisé
CWG 2474 C++98 supprimer un pointeur vers un objet d'un type similaire mais
différent entraînait un comportement indéfini
rendu bien défini
CWG 2624 C++98 les pointeurs obtenus à partir de
operator new [ ] non-allouant pouvaient être passés à delete [ ]
interdit
CWG 2758 C++98 la manière dont le contrôle d'accès était effectué pour
la fonction de désallocation et le destructeur n'était pas claire
clarifié

Voir aussi