默认stl分配器如何分配

How the default stl allocator allocates?

本文关键字:分配 何分配 stl 分配器 默认      更新时间:2023-10-16

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

class Foo{
 public:  
    void* operator new(size_t nbytes){
        return MemoryManager::GetInstance().AllocFooTypeMemory();
    }
    void operator delete(void* p)
    {
        MemoryManager::GetInstance().FreeFooTypeMemory(p);
    }
};

现在,我的问题是,当我创建一个Foo指针的STL容器时,它是如何工作的?这里写道,默认的STL分配器使用::operator new来分配容器中的内存。它什么时候用?我试着看看Foo的新功能是否在调用时被触发

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

但什么也没发生。

我有几个问题:

在这种情况下,分配器只为指针分配内存,这是对的吗?

这是否意味着当容器包含对象而不是指针时,分配器会在Foo上调用"new"?

同样,如果是,这是否意味着如果我已经使用池来分配对象中的内存(如Foo示例),那么我就不需要编写带有mem池的自定义分配器?

更新:

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

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

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

关于您的具体问题:

  • std::vector<Foo*>中,矢量将只分配指针。它怎么能做其他事情呢?

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

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

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

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

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