Maison > développement back-end > C++ > `make_shared` et `shared_ptr` initialisé par le constructeur : quelle est la différence en matière de performances et de sécurité des exceptions ?

`make_shared` et `shared_ptr` initialisé par le constructeur : quelle est la différence en matière de performances et de sécurité des exceptions ?

Barbara Streisand
Libérer: 2024-12-11 00:40:16
original
403 Les gens l'ont consulté

`make_shared` vs. Constructor-Initialized `shared_ptr`: What's the Performance and Exception Safety Difference?

Différence entre make_shared et Constructor-Initialized shared_ptr

Scénario

Considérez les extraits de code suivants :

std::shared_ptr<Object> p1 = std::make_shared<Object>("foo");
std::shared_ptr<Object> p2(new Object("foo"));
Copier après la connexion

Comprendre pourquoi make_shared est plus efficace que l'utilisation du constructeur shared_ptr nécessite directement un analyse étape par étape des opérations impliquées.

Comparaison des opérations

make_shared

  • Effectue une allocation de tas unique pour créer un bloc de mémoire contigu pour le contrôle bloc (métadonnées) et l'objet géré.

Constructeur-Initialisé shared_ptr

  • Appelle new Obj("foo"), qui crée une allocation de tas pour l'objet géré.
  • Ensuite, le constructeur shared_ptr est appelé, qui effectue une autre allocation de tas pour l'objet géré. bloc de contrôle.

Allocations de mémoire

make_shared n'alloue de la mémoire qu'une seule fois, tandis que le shared_ptr initialisé par le constructeur alloue de la mémoire deux fois. Cela rend make_shared plus efficace.

Sécurité des exceptions

En C 17, l'ordre d'évaluation des arguments de fonction a été révisé, éliminant un problème de sécurité des exceptions avec l'approche shared_ptr initialisée par le constructeur. Cependant, considérons l'exemple :

void F(const std::shared_ptr<Lhs> &lhs, const std::shared_ptr<Rhs> &rhs) { /* ... */ }

F(std::shared_ptr<Lhs>(new Lhs("foo")), std::shared_ptr<Rhs>(new Rhs("bar")));
Copier après la connexion

Si une exception est levée lors du constructeur Rhs, la mémoire allouée pour Lhs sera perdue car elle n'a pas été immédiatement transmise au constructeur shared_ptr. make_shared évite ce problème en éliminant cette étape intermédiaire.

Inconvénient de make_shared

Cependant, make_shared présente un inconvénient : puisqu'il alloue le bloc de contrôle et l'objet géré dans un seul bloc de tas, la mémoire pour les deux ne peuvent pas être désaffectés indépendamment. Cela signifie que des pointeurs faibles peuvent maintenir le bloc de contrôle en vie indéfiniment, empêchant potentiellement la désallocation du bloc de contrôle et de l'objet géré.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal