This question already has an answer here:
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.
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.
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.
Be aware that make_shared
limits you to using the default allocation/deallocation functions so if you want to have more control, make_shared
is not an option. In other words, something like
std::shared_ptr<uint8_t>(p, [](uint8_t *p){ /*user code */});
is impossible using make_shared
. One could use allocate_shared
instead, but only the allocator can be specified, not a deleter. Sometimes one need to control allocation and deletion of the wrapped class.
来源:https://stackoverflow.com/questions/18301511/stdshared-ptr-initialization-make-sharedfoo-vs-shared-ptrtnew-foo