使用make_shared时会发生什么 [英] What happens when using make_shared

查看:938
本文介绍了使用make_shared时会发生什么的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有兴趣,如果这两行代码是一样的:

  shared_ptr< int& sp(new int(1)); // double allocation? 
shared_ptr< int> sp(make_shared< int>(1)); //只是一个分配?

如果这是真的,有人可以解释为什么在第二行只有一个分配? p>

解决方案

第一种情况不执行双重分配,它执行两个分配,一个用于一个用于 shared_ptr 控制块



对于第二种情况, cppreference 有一个很好的解释,为什么 std :: make_shared 通常只执行一次内存分配(强调我正在处理):


此函数通常为T对象分配内存,为
shared_ptr的控制块分配单个内存分配(它是一个
标准中的非约束要求)
。相反,声明
std :: shared_ptr p(new T(Args ...))至少执行两次内存
分配,这可能产生不必要的开销。


std :: shared_ptr 部分说:


当通过调用std :: make_shared或
std :: allocate_shared创建shared_ptr时,块和
管理对象使用单个分配创建。管理对象
在控制块的数据成员中就位构建。当通过一个shared_ptr构造函数创建
shared_ptr时,
管理对象和控制块必须单独分配。在
这种情况​​下,控制块存储指向受管对象的指针。


这个 make_shared 描述与 C ++ 11 20.7.2.2.6 shared_ptr创建



< blockquote>

  template< class T,class ... Args> shared_ptr< T> make_shared(Args& ... args); 
template< class T,class A,class ... Args>
shared_ptr< T> allocate_shared(const A& a,Args& ... args);

[...]



:实现应该执行不超过一个内存
分配。 [注意:这提供了相当于
侵入式智能指针的效率。 -end note]



[注意:这些函数通常会分配比
sizeof(T)更多的内存以允许内部记账结构,例如
参考计数。 -end note]


Herb Sutter对使用 make_shared GotW#89解决方案:智能指针,并指出了一些优点:




  • 它减少了分配开销


  • 避免显式新增。

  • 避免异常安全问题。


b $ b

请注意,在使用 std :: weak_ptr 使用make_shared有一些缺点


I'm interested if these two lines of code are the same:

shared_ptr<int> sp(new int(1)); // double allocation?
shared_ptr<int> sp(make_shared<int>(1)); // just one allocation?

If this is true could someone please explain why is it only one allocation in the second line?

解决方案

The first case does not perform a double allocation, it performs two allocations, one for the managed object and one for the control block of the shared_ptr.

For the second case, cppreference has a good explanation for why std::make_shared usually only performs one memory allocation it says (emphasis mine going forward):

This function typically allocates memory for the T object and for the shared_ptr's control block with a single memory allocation (it is a non-binding requirement in the Standard). In contrast, the declaration std::shared_ptr p(new T(Args...)) performs at least two memory allocations, which may incur unnecessary overhead.

and from std::shared_ptr section it says:

When shared_ptr is created by calling std::make_shared or std::allocate_shared, the memory for both the control block and the managed object is created with a single allocation. The managed object is constructed in-place in a data member of the control block. When shared_ptr is created via one of the shared_ptr constructors, the managed object and the control block must be allocated separately. In this case, the control block stores a pointer to the managed object.

This make_shared description is consistent with the C++11 draft standard which says in section 20.7.2.2.6 shared_ptr creation

template<class T, class... Args> shared_ptr<T> make_shared(Args&&... args);
template<class T, class A, class... Args>
  shared_ptr<T> allocate_shared(const A& a, Args&&... args);

[...]

Remarks: Implementations should perform no more than one memory allocation. [ Note: This provides efficiency equivalent to an intrusive smart pointer. —end note ]

[ Note: These functions will typically allocate more memory than sizeof(T) to allow for internal bookkeeping structures such as the reference counts. —end note ]

Herb Sutter has a more detailed explanation of the advantages of using make_shared in GotW #89 Solution: Smart Pointers and points out some advantages:

  • It reduces allocation overhead
  • It improves locality.
  • Avoids an explicit new.
  • Avoids an exception safety issue.

Be aware that when using std::weak_ptr using make_shared has some disadvantages.

这篇关于使用make_shared时会发生什么的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆