(1) 当然最好检查实现,但您仍然可以从程序中进行一些检查。
控制块是动态分配的,因此为了确定其大小,您可以重载new运算符。
然后,您还可以检查std :: make_shared是否为您提供了一些控制块大小的优化。
在正确的实现中,我希望这将进行两个分配(objectA和控制块):
std::shared_ptr<A> i(new A())
然而,这只会进行一次分配(然后使用放置 new 初始化 objectA):
auto a = std::make_shared<A>()
考虑以下示例:
#include <iostream>
#include <memory>
void * operator new(size_t size)
{
std::cout << "Requested allocation: " << size << std::endl;
void * p = malloc(size);
return p;
}
class A {};
class B
{
int a[8];
};
int main()
{
std::cout << "Sizeof int: " << sizeof(int) << ", A(empty): " << sizeof(A) << ", B(8 ints): " << sizeof(B) << std::endl;
{
std::cout << "Just new:" << std::endl;
std::cout << "- int:" << std::endl;
std::shared_ptr<int> i(new int());
std::cout << "- A(empty):" << std::endl;
std::shared_ptr<A> a(new A());
std::cout << "- B(8 ints):" << std::endl;
std::shared_ptr<B> b(new B());
}
{
std::cout << "Make shared:" << std::endl;
std::cout << "- int:" << std::endl;
auto i = std::make_shared<int>();
std::cout << "- A(empty):" << std::endl;
auto a = std::make_shared<A>();
std::cout << "- B(8 ints):" << std::endl;
auto b = std::make_shared<B>();
}
}
我收到的输出(当然这取决于硬件架构和编译器):
Sizeof int: 4, A(empty): 1, B(8 ints): 32
Just new:
- int:
Requested allocation: 4
Requested allocation: 24
int类型的首次分配占用4个字节,下一个分配用于控制块,占用24个字节。
- A(empty):
Requested allocation: 1
Requested allocation: 24
- B(8 ints):
Requested allocation: 32
Requested allocation: 24
看起来控制块(很可能)是24个字节。
以下是使用make_shared的原因:
Make shared:
- int:
Requested allocation: 24
只需要分配一次,int + 控制块 = 24字节,比以前少了。
- A(empty):
Requested allocation: 24
- B(8 ints):
Requested allocation: 48
这里本来可能会有56个字节(32+24),但看起来实现进行了优化。如果您使用make_shared,控制块中不需要指向实际对象的指针,其大小仅为16个字节。
检查控制块大小的另一种可能方法是:
std::cout<< sizeof(std::enable_shared_from_this<int>);
在我的情况下:
16
在我的情况下,控制块的大小为16-24字节,具体取决于它是如何创建的。
std::shared_ptr
是一个模板,因此必须对编译器可见。你可以研究编译器实现的std::shared_ptr
并了解其工作原理。 - Sam Varshavchikstd::shared_ptr
的实现。除此之外,我认为std::shared_ptr
只是使用了原子操作,因此在这方面是“无锁”的。请注意,如果可能的话,最好根本不要在线程之间共享可变数据,在这种情况下,您可能需要更简单的引用计数指针,它不需要原子操作或锁定。 - Cubicstd::shared_ptr
是基于标准原子类型实现的。但无论如何,你为什么在意呢? - curiousguy