【问题标题】:Who allocates the memory for control block of shared_ptr when using custom new() operator with a class使用自定义 new() 运算符和类时谁为 shared_ptr 的控制块分配内存
【发布时间】:2021-06-18 21:01:03
【问题描述】:

假设我有这样的代码:

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() 创建。 控制块 的内存是使用::operator new()Foo::operator new() 创建的吗?如果是make_shared,是否会使用Foo::operator new() 分配整个单块内存?

【问题讨论】:

  • shared_ptr 永远不需要自己分配对象块。你传入了一个指针,它可以直接使用它。

标签: c++ shared-ptr new-operator


【解决方案1】:

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

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

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

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

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

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

3.11.3.6 ... allocate_shared 模板使用 a 的副本(为未指定的 value_type 反弹)来分配内存...

7 备注:(7.1) — 实现应该执行不超过一次的内存分配。 [注意:这提供了等效于侵入式智能指针的效率。 ——尾注]>

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

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

【讨论】:

    猜你喜欢
    • 2017-02-18
    • 1970-01-01
    • 2012-11-29
    • 2012-07-22
    • 2015-07-16
    • 1970-01-01
    • 2011-03-16
    • 1970-01-01
    相关资源
    最近更新 更多