std :: shared_ptr Exception Safety

Je viens de me rendre compte en lisant cette page que le constructeur de std :: shared_ptr avec un seul argument de pointeur n’est pas noexcept.

Par conséquent, le code suivant contient une fuite de mémoire possible:

std::shared_ptr p3 (new int); 

La raison en est que deux affectations pourraient se produire:

  • Le premier avant l’appel au constructeur
  • Le second dans le constructeur de shared_ptr (c’est ce qui se passe dans VS 2012 par exemple)

Deux questions ici:

Est-il vrai que si la deuxième allocation lève une exception, la mémoire de la première fuit?

Si la réponse est oui:

quel est le langage correct à utiliser std :: shared_ptr?

  • en utilisant make_shared
  • donnant la propriété de la première allocation à un std :: unique_ptr puis transférant la propriété
  • D’autres pensées ?

 template explicit shared_ptr(Y* p); 

[util.smartptr.shared.const] / 6 bad_alloc : bad_alloc ou une exception définie par l’implémentation lorsqu’une ressource autre que la mémoire n’a pas pu être obtenue.
[util.smartptr.shared.const] / 7 Sécurité des exceptions : Si une exception est levée, delete p est appelé.

Donc non, pas de fuite de mémoire.

Réponse tardive, mais il est préférable d’utiliser make_shared() pour la sécurité des exceptions, comme indiqué dans GotW # 102 : Le code suivant n’est pas protégé contre les exceptions:

  f( std::shared_ptr{ new T1 }, std::shared_ptr{ new T2 } ); 

Considérant que ce qui suit est:

 f( std::make_shared(), std::make_shared() );