Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there any reason not to use std::make_shared when constructing objects?

Tags:

c++

I can't think of any situation where

std::shared_ptr<Object> obj(new Object("foo", 1));

would be preferred to

auto obj = std::make_shared<Object>("foo", 1);

The latter always results in better locality and reduces memory fragmentation. Is there any situation, where you would prefer (or be forced) to use the first form, except interfacing with code returning raw pointers?

like image 435
Alex B Avatar asked Jan 12 '12 23:01

Alex B


People also ask

Why is make_shared more efficient?

One reason is because make_shared allocates the reference count together with the object to be managed in the same block of memory. OK, I got the point. This is of course more efficient than two separate allocation operations.

What is the use of make_shared?

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.

Why do we need 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.

In what situation is a shared_ptr more appropriate than a 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.


1 Answers

The latter always results in better locality and reduces memory fragmentation.

Not always. An implementation is encouraged to use a single allocation for the reference counted object and the reference count, but it is not required to do so.

Why might you not want to use std::make_shared? Consider the case where you have a large dynamically allocated object that you want owned by std::shared_ptr and you know that there will be weak references to this object that are likely to outlive the strong references to the object (perhaps there are many weak references and only one or two short-lived strong references).

In this case, std::make_shared would be a poor choice, assuming it allocates a single block that owns both the object and the reference count: the allocated block (which is large, remember) cannot be destroyed until there are no strong or weak references left to the object.

If you were to dynamically allocate the object yourself and pass the pointer to the std::shared_ptr constructor, the memory occupied by the object could be released as soon as there are no strong references remaining, even if there are still weak references.

like image 159
James McNellis Avatar answered Oct 07 '22 08:10

James McNellis