Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

std::shared_ptr initialization: make_shared<Foo>() vs shared_ptr<T>(new Foo) [duplicate]

What's the difference between:

std::shared_ptr<int> p = std::shared_ptr<int>( new int ); 

and

std::shared_ptr<int> p = std::make_shared< int >(); 

?

Which one should I prefer and why?

P. S. Pretty sure this must have been answered already, but I can't find a similar question.

like image 702
Violet Giraffe Avatar asked Aug 18 '13 16:08

Violet Giraffe


People also ask

Why should I use Make_shared?

As well as this efficiency, using make_shared means that you don't need to deal with new and raw pointers at all, giving better exception safety - there is no possibility of throwing an exception after allocating the object but before assigning it to the smart pointer.

What is std :: Make_shared?

std::make_sharedAllocates and constructs an object of type T passing args to its constructor, and returns an object of type shared_ptr<T> that owns and stores a pointer to it (with a use count of 1). This function uses ::new to allocate storage for the object.

Should I use shared_ptr or Unique_ptr?

Use unique_ptr when you want a single pointer to an object that will be reclaimed when that single pointer is destroyed. Use shared_ptr when you want multiple pointers to the same resource.

When should I use shared_ptr?

Use shared_ptr if you want to share ownership of a resource. Many shared_ptr can point to a single resource. shared_ptr maintains reference count for this propose. when all shared_ptr's pointing to resource goes out of scope the resource is destroyed.


2 Answers

Both examples are rather more verbose than necessary:

std::shared_ptr<int> p(new int);  // or '=shared_ptr<int>(new int)' if you insist auto p = std::make_shared<int>(); // or 'std::shared_ptr<int> p' if you insist 

What's the difference?

The main difference is that the first requires two memory allocations: one for the managed object (new int), and one for the reference count. make_shared should allocate a single block of memory, and create both in that.

Which one should I prefer and why?

You should usually use make_shared as it's more efficient. As noted in another answer, it also avoids any possibility of a memory leak, since you never have a raw pointer to the managed object.

However, as noted in the comments, it has a potential disadvantage that the memory won't be released when the object is destroyed, if there are still weak pointers preventing the shared count from being deleted.


EDIT 2020/03/06:

Further recommendations come also from the official Microsoft documentation with associated examples. Keep the focus on the Example 1 snippet:

Whenever possible, use the make_shared function to create a shared_ptr when the memory resource is created for the first time. make_shared is exception-safe. It uses the same call to allocate the memory for the control block and the resource, which reduces the construction overhead. If you don't use make_shared, then you have to use an explicit new expression to create the object before you pass it to the shared_ptr constructor. The following example shows various ways to declare and initialize a shared_ptr together with a new object.

like image 124
Mike Seymour Avatar answered Sep 20 '22 19:09

Mike Seymour


From en.cppreference.com

In contrast, the declaration std::shared_ptr<T> p(new T(Args...)) performs at least two memory allocations, which may incur unnecessary overhead.

Moreover, f(shared_ptr<int>(new int(42)), g()) can lead to memory leak if g throws an exception. This problem doesn't exist if make_shared is used.

So I would recommend the make_shared approach if possible.

like image 23
Adri C.S. Avatar answered Sep 19 '22 19:09

Adri C.S.