当对类使用自定义new()运算符时,谁为shared_ptr的控制块分配内存



假设我有这样的代码:

class Foo
{
private:
int x;
public:
void* operator new(size_t size);
void operator delete(void* p);
};

int main() {
auto ptr = std::shared_ptr<Foo>(new Foo());
return 0; 
}

shared_ptr将创建单独的控制块对象块制块的内存是使用::operator new()还是Foo::operator new()创建的?在make_shared的情况下,是否会使用Foo::operator new()分配整个内存块?

shared_ptr将创建单独的控制块和对象块。我想对象块的内存将使用Foo::操作符new((创建。

没有。您已经传入了指向对象的指针,因此它只需要一个控制块。事实上,我相信没有shared_ptr构造分配单个对象块,他们永远不需要它

控制块的内存是使用:operator new((还是Foo::operator new((创建的?

C++规范没有指定,但对于实现来说,明智的做法是将分配器重新绑定到Allocator<ControlBlock>并使用其allocate成员,这几乎肯定会使用::operator new()。它分配的是ControlBlock,而不是Foo

在make_shared的情况下,是否会使用Foo::operator new((分配整个内存块?

C++规范确实指定了这个:

3.11.3.6…allocate_shared模板使用一个(未指定值类型的反弹(的副本来分配内存。。。

7备注:(7.1(--实现应执行不超过一个内存分配。[注意:这提供了相当于侵入式智能指针的效率。--结束语]>

在这种情况下,实现将分配器重新绑定到Allocator<ControlAndObjectBlock>并使用其allocate成员,这几乎肯定会再次使用::operator new(),因为它分配的是ControlAndObjectBlock而不是Foo

summary:由于shared_ptr本身从未实际分配对象块,因此它永远不会使用Foo::operator new。但是,std::shared_ptr<Foo>(new Foo())表达式使用Foo::operator new()0分配Foo,然后根据该指针构造std::shared_ptr<Foo>

最新更新