使用make_shared时会发生什么 [英] What happens when using 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屋!