In this question, the "second variable" refers to this line:
auto ptr_res2(new Object("new"));
Not this one:
std::shared_ptr<Object> p2(new Object("foo"));
The best explanation of why make_shared
is more efficient with a single distribution is image comparison. Here is what std_shared_ptr<Object>(new Object)
looks like:

shared_ptr
has Widget*
, but it is not in the same memory block as the ref counts, since they were allocated separately. Widget*
was passed, and the ref count was allocated internally, so Widget
is in a separate memory space.
On the other hand, here's what it looks like with one highlight:

(I steal both paintings from Herb Sutter). We still need the Widget
and ref counting block, but instead the whole memory block is captured by a single call to new
/ malloc
only of sufficient size, therefore the Widget
and ref counting block is continuous in memory.
Barry source share