【问题标题】:How the default stl allocator allocates?默认的stl分配器是如何分配的?
【发布时间】:2014-12-07 19:29:28
【问题描述】:

我让我的对象使用重载的 new/delete 运算符,因为我使用内存池来分配它们的内存。 它们看起来像这样:

class Foo{

 public:  
    void* operator new(size_t nbytes){

        return MemoryManager::GetInstance().AllocFooTypeMemory();

    }
    void operator delete(void* p)
    {
        MemoryManager::GetInstance().FreeFooTypeMemory(p);
    }

};

现在,我的问题是,当我创建一个 Foo 指针的 STL 容器时它是如何工作的?Here 它写道,默认的 STL 分配器使用 ::operator new 在container.container.什么时候使用?我试着看看Foo的new在调用时是否被触发

std::vector<Foo*> fooVector;
fooVector.reserve(10);

但什么也没发生。

我有几个问题:

我是否正确暗示在这种情况下分配器只为指针分配内存?

这是否意味着当容器保存对象而不是指针时分配器在 Foo 上调用“new”?

如果是,是否意味着如果我已经使用内存池在对象中分配内存(如 Foo 示例),我不需要使用内存池编写自定义分配器?

更新:

为了清楚起见,我考虑到只有使用内存池重载 new/delete 的对象与这个问题有关。我完全知道没有 new/deleted 重载的对象仍然使用默认堆作为动态内存分配的来源。

【问题讨论】:

  • 不,您的代码仍在使用默认分配器
  • 我知道我仍然使用默认分配器,但它会使用 Foo 的“新”来分配吗?
  • 如果你从不告诉它使用Foo,它就不会使用Foo
  • FooFoo* 是不同的东西。
  • @T.C.我毫不怀疑他们是 ;)

标签: c++ memory-management stl allocator


【解决方案1】:

在您的情况下,重载 new 和 delete 运算符仅适用于 Foo 类。这意味着,以下调用使用您的自定义 new 和 deleteL:

Foo * p - new Foo();
delete p;

其余使用 new 和 delete 的动态内存分配使用默认值,而不是您的。 相反,您可以尝试过度使用全局 new 和 delete 运算符,而不是特定于 Foo。

【讨论】:

    【解决方案2】:

    默认分配器不能使用特定于类的operator new, 因为它不包含new 表达式;它调用 ::operator new 直接作用,分离分配和 初始化。

    在您的情况下,当然,您没有Foo 的容器, 但是Foo*,所以你在Foo中定义的任何东西都是无关紧要的 (并且您不能为指针定义 operator new)。

    关于您的具体问题:

    • std::vector&lt;Foo*&gt; 中,向量只会分配 指针。它还能做什么?

    • 如果容器包含Foo,而不是Foo*,则问题 比较复杂;默认分配器将使用::operator new 分配内存,::new (size_t, void*)... 构造对象。

    • 您不想将内存池用于 一个容器。如果容器是std::vector,则对象 将在连续的内存中,通常不应该采取 从池中,对于其他类型的容器,什么是 分配的通常根本不是Foo,而是更复杂一些 包含Foo 的类型。

    【讨论】:

    • 所以这意味着我必须提供自定义分配器来将默认 ::operator new 更改为 Foo 的重载分配器?这是你说的吗?
    • @MichaelIV: 是的,除了你正在构造一个指针容器之外,所以分配器根本不用于分配Foo 对象,使这一点毫无意义!
    • 太棒了!这正是我需要知道的。
    • @James 关于您的最后一点“您不想为容器中的对象使用内存池。”,为什么不呢?一般来说,为什么内存池会关心?如果我有一个内存池,我可以要求给我一个指向长度为 xyz 字节的内存块的指针(可以选择对齐 abc),那么究竟是什么反对使用带有 std::vector 的内存池?
    • @antred 这正是malloc 的一些实现所做的。如果free 在同一个线程中,则永远不会锁定。如果free 在不同的线程中,则有一个需要同步的块队列要释放; malloc 将来到这里,仅在需要时才真正释放这些块。大多数分配是不同步的,如果free在同一个线程中,也是不同步的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-05-03
    • 2018-02-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-08
    相关资源
    最近更新 更多