c++ - new 和 make_shared 用于共享指针

标签 c++ pointers shared-ptr make-shared

我遇到了 this @kerek SB 状态的帖子和答案之一

std::shared_ptr<Object> p1 = std::make_shared<Object>("foo");
std::shared_ptr<Object> p2(new Object("foo"));

In your code, the second variable is just a naked pointer, not a shared pointer at all.

Now on the meat. make_shared is (in practice) more efficient, because it allocates the reference control block together with the actual object in one single dynamic allocation. By contrast, the constructor for shared_ptr that takes a naked object pointer must allocate another dynamic variable for the reference count. The trade-off is that make_shared (or its cousin allocate_shared) does not allow you to specify a custom deleter, since the allocation is performed by the allocator.

(This does not affect the construction of the object itself. From Object's perspective there is no difference between the two versions. What's more efficient is the shared pointer itself, not the managed object.)

现在我有两个关于这篇文章的问题,如果有人能澄清一下,我将不胜感激

  1. 为什么第二个不是共享指针?这不会增加引用计数吗

  2. make_shared 如何只进行一次内存分配,而 new 如何进行两次内存分配 让 make_shared 更高效?

如果能对此做出一点澄清,我们将不胜感激。

最佳答案

在那个问题中,“第二个变量”指的是这一行:

auto ptr_res2(new Object("new")); // this creates an Object*

不是这个:

std::shared_ptr<Object> p2(new Object("foo")); // this creates a shared_ptr<Object>

为什么最好的解释make_shared一种分配更有效的方法是比较图像。这是std_shared_ptr<Object>(new Object)看起来像:

enter image description here

shared_ptr有一个 Widget* ,但它与 ref 计数器不在同一个内存块中,因为它们是单独分配的。 Widget*被传入,引用计数 block 在内部分配,这就是为什么 Widget是在一个单独的内存空间。

另一方面,这是一个分配的样子:

enter image description here

(我盗用了 Herb Sutter 的两张照片)。我们还需要一个 Widget和一个引用计数 block ,而是在对 new 的一次调用中获取整个内存块。/malloc , 刚好足够大,所以 Widget和 ref 计数 block 最终在内存中是连续的。

关于c++ - new 和 make_shared 用于共享指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27082860/

相关文章:

c++ - 如果您已经有一个 std::shared_ptr 可供使用,那么 std::enable_shared_from_this 有多有用?

c++ - shared_ptr 的子数据(类似子字符串?)

c++ - 如何将 Algol 68 Genia 语言转换为 C++ 语言

c - C语言结构体的动态内存分配

c - 从数组创建二叉树的问题

c - 使用 & 运算符和不使用 & 运算符的地址有什么区别?

c++ - 关于 boost::shared_ptr 的困惑

c++ - 试图理解 Boost Qi 解析为结构

c++ - SSE 半负载 (_mm_loadh_pi/_mm_loadl_pi) 发出警告

具有多个参数错误的 C++ 宏和模板