c++ - make_shared "evidence"与默认构造

标签 c++ memory-management smart-pointers

make_shared 为对象和引用计数器分配单个 block 。所以使用这种技术有明显的性能优势。

我在 VS2012 中做了简单的实验,我在寻找“证据”:

std::shared_ptr<Test> sp2 = std::make_shared<Test>();
std::shared_ptr<Test> sp(new Test());
// Test is a simple class with int 'm_value' member

调试时我在本地 View 中看到了类似这样的内容(删除了一些行)

-   sp2 shared_ptr {m_value=0 }  [make_shared] std::shared_ptr<Test>
+   _Ptr    0x01208dec {m_value=0 } Test *
+   _Rep    0x01208de0 make_shared  std::_Ref_count_base *

-   sp  shared_ptr {m_value=0 } [default] std::shared_ptr<Test>
+   _Ptr    0x01203c50 {m_value=0 } Test *
+   _Rep    0x01208d90 default  std::_Ref_count_base *

似乎sp2分配在0x01208de0(有一个ref计数器)然后在0x01208dec有一个Test对象。位置彼此非常接近。

在第二个版本中,我们有 0x01208d90 用于引用计数器,0x01203c50 用于对象。这些位置很远。

这是正确的输出吗?我的理解正确吗?

最佳答案

如果您阅读 cppreference's page for make_shared ,他们说:

This function allocates memory for the T object and for the shared_ptr's control block with a single memory allocation. In contrast, the declaration std::shared_ptr<T> p(new T(Args...)) performs two memory allocations, which may incur unnecessary overhead.

所以这是预期的行为,您对其进行了正确的解释。

当然,这是有道理的; shared_ptr怎么会控制你已经分配的对象的分配?与 make_shared ,你让它负责分配对象,这样它就可以在它想要的任何地方分配你的对象的空间,就在柜台旁边。

附录:正如 Pete Becker 在评论中指出的那样,标准的 §20.7.2.2.6/6 指出,鼓励但不要求实现仅执行一次分配。因此,不应依赖您观察到的这种行为,尽管可以肯定地说,如果您始终使用 make_shared,您不会有任何损失和收获。 .

关于c++ - make_shared "evidence"与默认构造,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14665935/

相关文章:

c++ - 调用带有编译错误的 C++ 方法

c++ - 根据情况在 if 语句中声明不同的数据类型 : how to shut up the compiler?

c++ - 了解内存池

c++ - 删除指向不完整类型和智能指针的指针

c++ - 为 RAII 包装 C 分配

C++11,std::atomic 在 clang 3.2 和 libc++ 中损坏了吗?

c++ - 对VS2010文本编辑器的好奇

c++ - 有没有新的 _malloca 等价物

Python - 入站出站参数

c++ - 如何make_shared派生类?