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

Who allocates the memory for control block of shared_ptr when using custom new() operator with a class

假设我有这样的代码:

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 将创建单独的 control-blockobject-block。我想对象块的内存将使用 Foo::operator new() 创建。 control-block 的内存是使用 ::operator new() 还是 Foo::operator new() 创建的?在 make_shared 的情况下,是否会使用 Foo::operator new() 分配整个单块内存?

The shared_ptr will create separate control-block and object-block. I suppose the memory for the object block will be created using the Foo::operator new().

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

Is the memory for the control-block created using ::operator new() or Foo::operator new()?

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

And in case of make_shared, would the entire single-block of memory be allocated using Foo::operator new()?

C++ 规范确实指定了这一点:

3.11.3.6 ... The allocate_shared templates use a copy of a (rebound for an unspecified value_type) to allocate memory...

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

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

总结:由于 shared_ptr 从来没有实际自己分配一个对象块,所以它永远不会使用 Foo::operator new。但是,您的 std::shared_ptr<Foo>(new Foo()) 表达式使用 Foo::operator new 分配一个 Foo,然后从该指针构造一个 std::shared_ptr<Foo>