Différence entre “détruire” “destructeur” “désallouer” dans std :: allocator?

Dans C ++ std::allocator , il existe trois méthodes relatives à un concept commun:

  • deallocate
  • destroy
  • destructeur

Je veux savoir:

  1. En quoi sont-ils différents les uns des autres du sharepoint vue de la gestion de la mémoire?
  2. quand devrais-je utiliser ceci mais pas cela?

Je vous remercie!


Edit: Doutes plus spécifiques:

Je suis désolé de généraliser au début, voici quelques points que je ne comprends pas.

  1. Que fait le destructeur? La documentation ne disait pas si la mémoire serait libérée automatiquement lorsque le destructeur s’appelle
  2. Le destroy est utilisé pour appeler le destructeur sur un object, que veut dire “object” ici?

Merci encore!

Les brèves descriptions de la documentation de cppreference.com expliquent très bien les différences.

entrez la description de l'image ici

“1. Que fait destructeur? La documentation ne dit pas si la mémoire sera libérée automatiquement lorsque le destructeur s’appelle”

Toute mémoire occupée par l’instance std::allocator sera libérée comme d’habitude.

“2. Le destroy est utilisé pour appeler le destructeur sur un object, que signifie” object “ici?”

Encore une fois pour citer la documentation détaillée

  void destroy( pointer p ); // 1) template< class U > // 2) void destroy( U* p ); 

Appelle le destructeur de l’object désigné par p
1) Appels ((T*)p)->~T()
2) Appels p->~U()

Objet dans ce contexte signifie un object de type T géré par l’instance std::allocator .

La réponse à votre question réside dans la relation entre l’opération de suppression et le destructeur d’object.

désallouer (pointeur p, taille size_type)

 - calls "delete p"; - "delete" implicitly calls the destructor of the object at p; - frees/deallocates the memory where the object pointed by p was stored 

détruire (pointeur p)

 - calls only the destructor ((T*)p)->~T() - the memory at addres p will not be freed/deallocated 

A propos des destructeurs

  • L’appel explicite d’un destructeur n’appelle pas implicitement delete sur l’object qui a appelé le destructeur.
  • note: ~ MyClass () {delete this; } n’est pas une exception car il va générer une violation d’access.

Pourquoi est-il judicieux d’appeler le destructeur sans utiliser delete?

  • un object alloué de manière dinamique peut avoir des pointeurs sur des objects alloués en tant que variables membres. Si vous souhaitez libérer cette mémoire sans supprimer l’object d’origine qui contient les pointeurs, appelez le destructeur annulé, car celui par défaut ne le ferait pas.

    Dans l’exemple suivant, je vais essayer de banaliser le problème mentionné.

    Exemple:

     template < class T,class U > class MyClass{ 
     private: T* first_pointer; U* second_pointer; public: MyClass(){ //constructor: first_pointer=new T(); //allocate memory for pointer variables second_pointer=new U(); //with non-argument constructors T() and U() } ~MyClass(){ //destructor is overriden delete first_pointer; //because the default-destructor delete second_pointer; //will not release the memory allocated for } //first_pointer and second_pointer void set_first(const T& val){ first_pointer=new T(val); 

    }

    void set_second (const U & val) {

      second_pointer=new U(val); 

    }

    };

    void some_function (void) {

    MyClass * object;

    object = new MyClass (); // par exemple: l'object alloué est à l'emplacement de mémoire 00123A

    // Disons qu'après un certain temps, vous n'avez plus besoin de la mémoire pour "first_pointer" et
    // "second_pointer" mais vous voulez conserver la mémoire pour "object".
    // donc on appelle le destructeur.

    object-> ~ MyClass (); // la mémoire à l'adresse 00123A est toujours réservée à notre object
    // mais les emplacements first_pointer et second_pointer
    // sont désalloués.

    // puis disons qu'après un certain temps nous devons définir les variables de membre
    object-> set_first (T (...)) // les arguments dépendent des constructeurs définis
    object-> set_second (U (...)) // pour T et U. Peu importe dans cet exemple

    // après un certain temps, nous n'avons pas besoin de l'object et de ses parties
    // donc on appelle delete sur l'object

    supprimer un object; // appelle notre destructeur pour libérer la mémoire pointée
    // par first_pointer et second_pointer.
    // alors il libère la mémoire à "00123A" où notre object était

    }

    Revenons maintenant à std :: allocator et destroy () vs deallocate ()

    allocateur est une abstraction (interface) pour l’allocation de mémoire. Il sépare allocation de destruction, désaffectation de destruction.

    destroy () – “détruit” des données sur un emplacement mémoire rendant l’object inutilisable, mais la mémoire est toujours disponible (l’object peut être reconstruit)

    deallocate () – “libère” l’emplacement de la mémoire où se trouvait l’object, de sorte que le stockage ne soit plus utilisable pour la construction de l’object sur cet emplacement. entrez le code ici