Namespaces
Variants

operator delete , operator delete[]

From cppreference.net
< cpp ‎ | memory ‎ | new
Utilities library
Memory management library
( exposition only* )
Allocators
Uninitialized memory algorithms
Constrained uninitialized memory algorithms
Memory resources
Uninitialized storage (until C++20)
( until C++20* )
( until C++20* )
( until C++20* )

Garbage collector support (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
Défini dans l'en-tête <new>
Fonctions de désallocation usuelles remplaçables
(1)
void operator delete ( void * ptr ) throw ( ) ;
(jusqu'à C++11)
void operator delete ( void * ptr ) noexcept ;
(depuis C++11)
(2)
void operator delete [ ] ( void * ptr ) throw ( ) ;
(jusqu'à C++11)
void operator delete [ ] ( void * ptr ) noexcept ;
(depuis C++11)
void operator delete ( void * ptr, std:: align_val_t al ) noexcept ;
(3) (depuis C++17)
void operator delete [ ] ( void * ptr, std:: align_val_t al ) noexcept ;
(4) (depuis C++17)
void operator delete ( void * ptr, std:: size_t sz ) noexcept ;
(5) (depuis C++14)
void operator delete [ ] ( void * ptr, std:: size_t sz ) noexcept ;
(6) (depuis C++14)
void operator delete ( void * ptr, std:: size_t sz,
std:: align_val_t al ) noexcept ;
(7) (depuis C++17)
void operator delete [ ] ( void * ptr, std:: size_t sz,
std:: align_val_t al ) noexcept ;
(8) (depuis C++17)
Fonctions de désallocation de placement remplaçables
(9)
void operator delete ( void * ptr, const std:: nothrow_t & tag ) throw ( ) ;
(jusqu'à C++11)
void operator delete ( void * ptr, const std:: nothrow_t & tag ) noexcept ;
(depuis C++11)
(10)
void operator delete [ ] ( void * ptr, const std:: nothrow_t & tag ) throw ( ) ;
(jusqu'à C++11)
void operator delete [ ] ( void * ptr, const std:: nothrow_t & tag ) noexcept ;
(depuis C++11)
void operator delete ( void * ptr, std:: align_val_t al,
const std:: nothrow_t & tag ) noexcept ;
(11) (depuis C++17)
void operator delete [ ] ( void * ptr, std:: align_val_t al,
const std:: nothrow_t & tag ) noexcept ;
(12) (depuis C++17)
Fonctions de désallocation de placement non-allouantes
(13)
void operator delete ( void * ptr, void * place ) throw ( ) ;
(jusqu'à C++11)
void operator delete ( void * ptr, void * place ) noexcept ;
(depuis C++11)
(14)
void operator delete [ ] ( void * ptr, void * place ) throw ( ) ;
(jusqu'à C++11)
void operator delete [ ] ( void * ptr, void * place ) noexcept ;
(depuis C++11)
Fonctions de désallocation de placement définies par l'utilisateur
void operator delete ( void * ptr, args... ) ;
(15)
void operator delete [ ] ( void * ptr, args... ) ;
(16)
Fonctions de désallocation usuelles spécifiques à la classe
void T :: operator delete ( void * ptr ) ;
(17)
void T :: operator delete [ ] ( void * ptr ) ;
(18)
void T :: operator delete ( void * ptr, std:: align_val_t al ) ;
(19) (depuis C++17)
void T :: operator delete [ ] ( void * ptr, std:: align_val_t al ) ;
(20) (depuis C++17)
void T :: operator delete ( void * ptr, std:: size_t sz ) ;
(21)
void T :: operator delete [ ] ( void * ptr, std:: size_t sz ) ;
(22)
void T :: operator delete ( void * ptr, std:: size_t sz, std:: align_val_t al ) ;
(23) (depuis C++17)
void T :: operator delete [ ] ( void * ptr, std:: size_t sz, std:: align_val_t al ) ;
(24) (depuis C++17)
Fonctions de désallocation placement spécifiques à la classe
void T :: operator delete ( void * ptr, args... ) ;
(25)
void T :: operator delete [ ] ( void * ptr, args... ) ;
(26)
Fonctions de désallocation de destruction habituelles spécifiques à la classe
void T :: operator delete ( T * ptr, std:: destroying_delete_t ) ;
(27) (depuis C++20)
void T :: operator delete ( T * ptr, std:: destroying_delete_t ,
std:: align_val_t al ) ;
(28) (depuis C++20)
void T :: operator delete ( T * ptr, std:: destroying_delete_t , std:: size_t sz ) ;
(29) (depuis C++20)
void T :: operator delete ( T * ptr, std:: destroying_delete_t ,
std:: size_t sz, std:: align_val_t al ) ;
(30) (depuis C++20)

Libère le stockage précédemment alloué par un operator new ou un operator new[] correspondant. Ces fonctions de libération sont appelées par les delete et delete [ ] expressions et par les placement new expressions pour libérer la mémoire après la destruction (ou l'échec de construction) d'objets ayant une durée de stockage dynamique. Elles peuvent également être appelées en utilisant la syntaxe d'appel de fonction classique.

1-12) Fonctions de désallocation remplaçables. La bibliothèque standard fournit des implémentations par défaut pour ces fonctions, pour les effets des implémentations par défaut, voir ci-dessous .
1-8) Appelé par les expressions delete et delete [ ] . Invalide tout ptr non nul.
9-12) Appelé par les expressions de placement new lors d'une défaillance d'initialisation . operator delete [ ] invalide tout ptr non nul.
Si ptr n'est pas un pointeur nul et qu'une des conditions suivantes est satisfaite, le comportement est indéfini :
  • Pour operator delete , la valeur de ptr ne représente pas l'adresse d'un bloc de mémoire alloué par un appel antérieur à (éventuellement remplacé) operator new ( std:: size_t ) (pour les surcharges (1,5,9) ) ou operator new ( std:: size_t , std:: align_val_t ) (pour les surcharges (3,7,11) ) qui n'a pas été invalidé par un appel intermédiaire à operator delete .
  • Pour operator delete [ ] , la valeur de ptr ne représente pas l'adresse d'un bloc de mémoire alloué par un appel antérieur à (éventuellement remplacé) operator new [ ] ( std:: size_t ) (pour les surcharges (2,6,10) ) ou operator new [ ] ( std:: size_t , std:: align_val_t ) (pour les surcharges (4,8,12) ) qui n'a pas été invalidé par un appel intermédiaire à operator delete [ ] .
13,14) Appelé par les expressions de placement new qui ont invoqué une fonction d'allocation de placement non-allouante lorsqu'une partie de l'initialisation dans l'expression se termine en lançant une exception. N'effectue aucune action.
15-30) Fonctions de désallocation définies par l'utilisateur appelées par les expressions delete , delete [ ] et new de placement.
27-30) Si défini, delete les expressions n'exécutent pas le destructeur pour * ptr avant d'effectuer un appel à operator delete . Au lieu de cela, l'invocation directe du destructeur telle que par ptr - > ~T ( ) ; devient la responsabilité de cet operator delete .

Surcharges ( 1-8 ) sont implicitement déclarées dans chaque unité de traduction même si l'en-tête <new> n'est pas inclus.

Voir delete expression pour les critères de sélection de surcharge.

Table des matières

Paramètres

ptr - pointeur vers un bloc mémoire à désallouer ou un pointeur nul
sz - la taille qui a été passée à la fonction d'allocation correspondante
place - pointeur utilisé comme paramètre de placement dans le placement new correspondant
tag - balise de désambiguïsation de surcharge correspondant à celle utilisée par l'opérateur new non-lançant
al - alignement de l'objet ou de l'élément de tableau qui a été alloué
args - paramètres arbitraires correspondant à une fonction d'allocation de placement (peut inclure std::size_t et std::align_val_t )

Exceptions

Toutes les fonctions de désallocation sont noexcept ( true ) sauf indication contraire dans la déclaration.

(depuis C++11)

Si une fonction de désallocation se termine en lançant une exception, le comportement est indéfini , même si elle est déclarée avec noexcept ( false ) (depuis C++11) .

Remplacements globaux

Surcharges ( 1-12 ) sont remplaçables . Les effets des versions par défaut sont :

1) Si ptr est nul, ne fait rien. Sinon, récupère l'espace mémoire alloué par l'appel précédent à operator new .
2) Appelle operator delete ( ptr ) comme si la surcharge (1) pouvait récupérer l'espace mémoire alloué par l'appel précédent à operator new [ ] .
3) Identique à (1) .
4) Appelle operator delete ( ptr, al ) comme si la surcharge (3) pouvait récupérer le stockage alloué par l'appel précédent à operator new [ ] .
5) Appelle operator delete ( ptr ) .
6) Appelle operator delete [ ] ( ptr ) .
7) Appelle operator delete ( ptr, al ) .
8) Appelle operator delete [ ] ( ptr, al ) .
9) Appelle operator delete ( ptr ) .
10) Appelle operator delete [ ] ( ptr ) .
11) Appelle operator delete ( ptr, al ) .
12) Appelle operator delete [ ] ( ptr, al ) .

Opérateurs globaux operator de remplacement new / delete :

#include <cstdio>
#include <cstdlib>
#include <new>
// no inline, required by [replacement.functions]/3
void* operator new(std::size_t sz)
{
    std::printf("1) new(size_t), size = %zu\n", sz);
    if (sz == 0)
        ++sz; // avoid std::malloc(0) which may return nullptr on success
    if (void *ptr = std::malloc(sz))
        return ptr;
    throw std::bad_alloc{}; // required by [new.delete.single]/3
}
// no inline, required by [replacement.functions]/3
void* operator new[](std::size_t sz)
{
    std::printf("2) new[](size_t), size = %zu\n", sz);
    if (sz == 0)
        ++sz; // avoid std::malloc(0) which may return nullptr on success
    if (void *ptr = std::malloc(sz))
        return ptr;
    throw std::bad_alloc{}; // required by [new.delete.single]/3
}
void operator delete(void* ptr) noexcept
{
    std::puts("3) delete(void*)");
    std::free(ptr);
}
void operator delete(void* ptr, std::size_t size) noexcept
{
    std::printf("4) delete(void*, size_t), size = %zu\n", size);
    std::free(ptr);
}
void operator delete[](void* ptr) noexcept
{
    std::puts("5) delete[](void* ptr)");
    std::free(ptr);
}
void operator delete[](void* ptr, std::size_t size) noexcept
{
    std::printf("6) delete[](void*, size_t), size = %zu\n", size);
    std::free(ptr);
}
int main()
{
    int* p1 = new int;
    delete p1;
    int* p2 = new int[10]; // guaranteed to call the replacement in C++11
    delete[] p2;
}

Sortie possible :

// Compiled with GCC-5 in C++17 mode to obtain the following:
1) op new(size_t), size = 4
4) op delete(void*, size_t), size = 4
2) op new[](size_t), size = 40
5) op delete[](void* ptr)

Les surcharges de operator delete et operator delete [ ] avec des paramètres supplémentaires définis par l'utilisateur ("formes de placement", ( 15,16 ) ) peuvent être déclarées au niveau global comme d'habitude, et sont appelées par les formes de placement correspondantes des expressions new si un constructeur de l'objet en cours d'allocation lève une exception.

Les formes de placement de la bibliothèque standard de operator delete et de operator delete [ ] ( 13,14 ) ne peuvent pas être remplacées et ne peuvent être personnalisées que si l'expression de placement new n'a pas utilisé la syntaxe :: new , en fournissant un placement delete spécifique à la classe ( 25,26 ) avec une signature correspondante : void T :: operator delete ( void * , void * ) ou void T :: operator delete [ ] ( void * , void * ) .

Surcharges spécifiques à la classe

Fonctions de désallocation ( 17-24 ) peuvent être définies comme fonctions membres statiques d'une classe. Ces fonctions de désallocation, si elles sont fournies, sont appelées par les expressions delete lors de la suppression d'objets ( 17,19,21 ) et de tableaux ( 18,20,22 ) de cette classe, sauf si l'expression delete a utilisé la forme :: delete qui contourne la recherche dans la portée de la classe. Le mot-clé static est optionnel pour ces déclarations de fonctions : que le mot-clé soit utilisé ou non, la fonction de désallocation est toujours une fonction membre statique.

L'expression delete recherche le nom de la fonction de désallocation appropriée en commençant par la portée de la classe (la forme tableau recherche dans la portée de la classe des éléments du tableau) et procède à la portée globale si aucun membre n'est trouvé comme d'habitude. Notez que, conformément aux règles de recherche de nom , toute fonction de désallocation déclarée dans la portée de la classe masque toutes les fonctions de désallocation globales.

Si le type statique de l'objet en cours de suppression diffère de son type dynamique (comme lors de la suppression d'un objet polymorphe via un pointeur vers la base), et si le destructeur dans le type statique est virtuel, la forme à objet unique de delete commence la recherche du nom de la fonction de désallocation à partir du point de définition du remplacement final de son destructeur virtuel. Quelle que soit la fonction de désallocation qui serait exécutée à l'exécution, la version statiquement visible de operator delete doit être accessible pour permettre la compilation. Dans les autres cas, lors de la suppression d'un tableau via un pointeur vers la base, ou lors de la suppression via un pointeur vers la base avec un destructeur non virtuel, le comportement est indéfini.

Si la surcharge à un seul argument ( 17,18 ) n'est pas fournie, mais que la surcharge prenant en compte la taille avec std::size_t comme second paramètre ( 21,22 ) est fournie, la forme prenant en compte la taille est appelée pour la désallocation normale, et l'environnement d'exécution C++ passe la taille de l'objet à désallouer comme second argument. Si les deux formes sont définies, la version ne prenant pas en compte la taille est appelée.

#include <cstddef>
#include <iostream>
// fonctions de désallocation dimensionnées spécifiques à la classe
struct X
{
    static void operator delete(void* ptr, std::size_t sz)
    {
        std::cout << "custom delete for size " << sz << '\n';
        ::operator delete(ptr);
    }
    static void operator delete[](void* ptr, std::size_t sz)
    {
        std::cout << "custom delete for size " << sz << '\n';
        ::operator delete[](ptr);
    }
};
int main()
{
    X* p1 = new X;
    delete p1;
    X* p2 = new X[10];
    delete[] p2;
}

Sortie possible :

custom delete for size 1
custom delete for size 18

Les surcharges de operator delete et operator delete [ ] avec des paramètres supplémentaires définis par l'utilisateur ("formes de placement", ( 25,26 ) ) peuvent également être définies comme membres de classe. Lorsque l'expression de placement new échoué recherche la fonction de placement delete correspondante à appeler, elle commence la recherche dans la portée de la classe avant d'examiner la portée globale, et recherche la fonction dont la signature correspond au placement new :

#include <cstddef>
#include <iostream>
#include <stdexcept>
struct X
{
    X() { throw std::runtime_error("X(): std::runtime_error"); }
    // custom placement new
    static void* operator new(std::size_t sz, bool b)
    {
        std::cout << "custom placement new called, b = " << b << '\n';
        return ::operator new(sz);
    }
    // custom placement delete
    static void operator delete(void* ptr, bool b)
    {
        std::cout << "custom placement delete called, b = " << b << '\n';
        ::operator delete(ptr);
    }
};
int main()
{
    try
    {
        [[maybe_unused]] X* p1 = new (true) X;
    }
    catch (const std::exception& ex)
    {
        std::cout << ex.what() << '\n';
    }
}

Sortie :

custom placement new called, b = 1
custom placement delete called, b = 1
X(): std::runtime_error

Si l'opérateur delete au niveau de la classe operator delete est une fonction template, il doit avoir le type de retour void , le premier argument void * , et il doit avoir deux paramètres ou plus. En d'autres termes, seules les formes de placement peuvent être des templates. Une instance de template n'est jamais une fonction de désallocation usuelle, quelle que soit sa signature. La spécialisation du template operator delete est choisie avec la déduction d'arguments template .

Notes

L'appel à la fonction spécifique à la classe T :: operator delete sur une classe polymorphe est le seul cas où une fonction membre statique est appelée via une dispatch dynamique.

Les fonctions suivantes doivent être thread-safe :

Les appels à ces fonctions qui allouent ou désallouent une unité de stockage particulière se produisent dans un ordre total unique, et chaque appel de désallocation se produit-avant la prochaine allocation (le cas échéant) dans cet ordre.

(depuis C++11)
Macro de test de fonctionnalité Valeur Std Fonctionnalité
__cpp_sized_deallocation 201309L (C++14) Désallocation dimensionnée
__cpp_impl_destroying_delete 201806L (C++20) Opérateur delete destructeur (support du compilateur)
__cpp_lib_destroying_delete 201806L (C++20) Opérateur delete destructeur (support de la bibliothèque)

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 Appliqué à Comportement tel que publié Comportement correct
CWG 220 C++98 les fonctions de désallocation définies par l'utilisateur pouvaient lever des exceptions lever une exception depuis une fonction de désallocation
entraîne un comportement indéfini
CWG 1438 C++98 toute utilisation d'une valeur de pointeur invalide était un comportement indéfini seules l'indirection et la désallocation le sont
LWG 206 C++98 le remplacement de ( 2 ) n'affectait pas le comportement par défaut de ( 10 ) le comportement par défaut
change en conséquence
LWG 298 C++98 le remplacement de ( 1 ) n'affectait pas le comportement par défaut de ( 9 ) le comportement par défaut
change en conséquence
LWG 404 C++98 les remplacements des fonctions de désallocation remplaçables
pouvaient être déclarés inline
interdit, aucun diagnostic requis
LWG 2458 C++14 les surcharges prenant ( void * , std:: size_t , const
std:: nothrow_t & ) étaient spécifiées, mais ne pouvaient jamais être appelées
surcharges superflues supprimées

Voir aussi

[static] (C++23)
désalloue la mémoire précédemment obtenue de operator new
(fonction membre statique publique de std::generator<Ref,V,Allocator>::promise_type )
fonctions d'allocation
(fonction)
(obsolète en C++17) (supprimé en C++20)
libère le stockage non initialisé
(fonction template)
désalloue la mémoire précédemment allouée
(fonction)