The documentation states that std::make_shared<T>
typically allocates memory for T
and the smart pointer's control block at once in contrast to std::shared_pointer<T>(new T)
, which performs two allocations. Does it mean it is more efficient and therefore a one should always use std::make_shared
if possible?
The same question about Qt equivalent - QSharedPointer
. According to the docs the QSharedPointer
internals and the object are allocated in one single memory allocation, which could help reduce memory fragmentation in a long-running application. Does it mean QSharedPointer<T>::create()
is the preferred one?
class MyClass {};
QSharedPointer<MyClass> ptr1 = QSharedPointer<MyClass>::create(); // better
QSharedPointer<MyClass> ptr2(new MyClass); // worse
std::make_shared
is preferred in almost every case. However, if you use weak pointers, you can easily get into a "memory leak" situation where memory is kept around far longer than you would think at first glance (after all shared_ptr
s are gone).
As long as there is a std::weak_ptr
associated with a std::shared_ptr
control block, the control block must remain. Since std::make_shared
creates a single memory allocation for both the control block and the data, if the control block remains, the data must remain, too. With std::shared_ptr
, the there are two allocations, so they can be cleaned up independently.
So, if you're not using std::weak_ptr
(additional caveats below), absolutely always prefer std::make_shared
for benefits including the number of allocations and exception safety. If you are using std::weak_ptr
, you must be much more thoughtful about your design.
Modern Effective C++ chapter 4 is dedicated to how/when to use different smart pointers. It's a concise book for existing c++ programmers to catch up on the new features in c++11/14, including smart pointers.
edit: as @midor mentions, you there is also simply no option to provide a custom deleter when using std::make_shared
. Also, if the type T has different constructors that could be called with the same type but one with ()
and one with {}
, then it will always prefer the one with ()
. For example std::make_shared<std::vector>(10,10)
calls std::vector(10,10)
not std::vector{10,10}
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With