Are there any downsides with using make_shared to create a shared_ptr

C++BoostShared Ptr

C++ Problem Overview


Are there any downsides with using make_shared<T>() instead of using shared_ptr<T>(new T).

Boost documentation states

> There have been repeated requests from > users for a factory function that > creates an object of a given type and > returns a shared_ptr to it. Besides > convenience and style, such a function > is also exception safe and > considerably faster because it can use > a single allocation for both the > object and its corresponding control > block, eliminating a significant > portion of shared_ptr's construction > overhead. This eliminates one of the > major efficiency complaints about > shared_ptr.

C++ Solutions


Solution 1 - C++

In addition to the points presented by @deft_code, an even weaker one:

  • If you use weak_ptrs that live after all the shared_ptrs to a given object have died, then this object's memory will live in memory along with the control block until the last weak_ptr dies. In other words the object is destroyed but not deallocated until the last weak_ptr is destroyed.

Solution 2 - C++

I know of at least two.

  • You must be in control of the allocation. Not a big one really, but some older api's like to return pointers that you must delete.
  • No custom deleter. I don't know why this isn't supported, but it isn't. That means your shared pointers have to use a vanilla deleter.

Pretty weak points. so try to always use make_shared.

Solution 3 - C++

From http://www.codesynthesis.com/~boris/blog/2010/05/24/smart-pointers-in-boost-tr1-cxx-x0/

The other drawback of the make_shared() implementation is the increase in the object code size. Due to the way this optimization is implemented, an additional virtual table as well as a set of virtual functions will be instantiated for each object type that you use with make_shared().

Solution 4 - C++

Additionally, make_shared is not compatible with the factory pattern. This is because the call to make_shared within your factory function calls the library code, which in turn calls new, which it doesn't have access to, since it cannot call the class's private constructor(s) (constructor(s) should be private, if you follow the factory pattern correctly).

Solution 5 - C++

With make shared you can not specify how allocation and deallocation of the held object will be done.

When that is desired, use std::allocate_shared<T> instead:

std::vector<std::shared_ptr<std::string>> avec; 
std::allocator<std::string> aAllocator;
avec.push_back(std::allocate_shared<std::string>(aAllocator,"hi there!"));

Note that the vector does not need to be informed about the allocator!

For making a custom allocator, have a look here https://stackoverflow.com/a/542339/1149664

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionTobias FuruholmView Question on Stackoverflow
Solution 1 - C++sbkView Answer on Stackoverflow
Solution 2 - C++deft_codeView Answer on Stackoverflow
Solution 3 - C++Viktor SehrView Answer on Stackoverflow
Solution 4 - C++Rok StrnišaView Answer on Stackoverflow
Solution 5 - C++Johan LundbergView Answer on Stackoverflow