web-dev-qa-db-fra.com

Unique_ptr :: release () appelle-t-il le destructeur?

Ce code est-il correct?

auto v =  make_unique<int>(12);
v.release();     // is this possible?

Est-ce équivalent à delete d'un pointeur brut?

53
Zeukis

Non, le code provoque une fuite de mémoire. release est utilisé pour libérer la propriété de l'objet géré sans le supprimer:

auto v = make_unique<int>(12);  // manages the object
int * raw = v.release();        // pointer to no-longer-managed object
delete raw;                     // needs manual deletion

Ne le faites pas sauf si vous avez une bonne raison de jongler avec la mémoire brute sans filet de sécurité.

Pour supprimer l'objet, utilisez reset.

auto v = make_unique<int>(12);  // manages the object
v.reset();                      // delete the object, leaving v empty
114
Mike Seymour

Ce code est-il correct?

Utilisez la fonction std::unique_ptr<>::reset() pour supprimer le pointeur interne brut:

auto v =  std::make_unique<int>(12);
v.reset(); // deletes the raw pointer

Une fois cette opération terminée, std::unique_ptr<>::get() renverra nullptr (sauf si vous avez fourni un paramètre non -nullptr à std::unique_ptr<>::reset()).

22
Johann Gerell

Ce code est-il correct?

Ce n'est pas et va fuir.

release() laissez simplement le code appelant reprendre possession de la mémoire que le unique_ptr a gardée jusqu'à ce qu'il soit appelé. Si vous n'affectez pas le pointeur renvoyé par release(), vous aurez juste une fuite.

Une suppression explicite pour un unique_ptr Serait reset(). Mais rappelez-vous que unique_ptr Sont là pour que vous n'ayez pas à gérer directement la mémoire qu'ils détiennent. Autrement dit, vous devez savoir qu'un unique_ptr Supprimera en toute sécurité le pointeur brut sous-jacent une fois qu'il sera hors de portée.

Vous devriez donc avoir une très bonne raison d'effectuer la gestion manuelle de la mémoire sur un objet de gestion automatique de la mémoire.

17
JBL

release perdra votre pointeur brut puisque vous ne l'attribuez à rien.

Il est destiné à être utilisé pour quelque chose comme

int* x = v.release();

Ce qui signifie que v ne gère plus la durée de vie de ce pointeur, il délègue la propriété du pointeur brut à x. Si vous ne faites que release sans rien affecter, vous perdez le pointeur brut.

11
CoryKramer

cela peut être un peu délicat pour des types arbitraires:

  unique_ptr<Foo> v = get_me_some_foo();  // manages the object
  Foo * raw = v.release();        // pointer to no-longer-managed object
  delete raw;

est presque correct.

  unique_ptr<Foo> v = get_me_some_foo();  // manages the object
  Foo * ptr = v.release();        // pointer to no-longer-managed object
  v.get_deleter() ( ptr );

celui-ci serait correct dans toutes les situations; il peut y avoir un deleter personnalisé défini sur le type Foo, mais utiliser le deleter renvoyé par l'objet unique_ptr convient à tous les cas.

2
MichaelMoser