vector如何使用默认分配器?

时间:2013-09-19 16:23:48

标签: c++

当我研究STL时,我已经通过分配器,我在互联网上找到了很多东西,或多或少我了解他们做了什么。我看过一个自定义分配器,看看它们是如何实现的,但我的问题是它们是如何被容器使用的,让我们说到Vector中?

他们总是说矢量正在使用DEFAULT分配器。例如,空向量构造函数是:

   explicit vector (const allocator& alloc = allocator());

但是vector如何使用allocator?

在场景后面的vector何时何地使用Allocator :: allocate()和Allocator :: construct()?

知道为什么需要自定义分配器,它会改变什么?

3 个答案:

答案 0 :(得分:2)

正如@BenjaminLindley所提到的,有很多地方可以在容器内使用分配器。一个例子是push_back,它使用分配器特征在容器内构建其参数的副本

标准(23.2.3)将push_back描述为:

a.push_back(t)
     

附加t的副本。要求:T应为CopyInsertable到X。

稍后,术语CopyInsertable定义为:

  

T是CopyInsertable进入X意味着,除了T之外   将MoveInsertable移入X,以下表达式格式正确:

allocator_traits<A>::construct(a, p, t)

......可以变成:

a.construct(p, t)

...有效地使用分配器a在位置t构建p的副本。

答案 1 :(得分:2)

不同的编译器使用STL的不同实现,并且由这些实现来决定它们如何使用分配器。这可能会导致一些不幸的结果。

例如,我主要使用基于ARM体系结构的嵌入式系统,有一次,我试图基于固定大小的内存块实现自己的分配器,以便与list,{{1}一起使用}和map(我没想到它适用于set,因为足够大的矢量会超过块的大小)。在此过程中,我发现ARM编译器v3.1使用了STL的RogueWave实现版本,其中一些容器对Allocators的行为做出了某些假设。例如,在vectormap的情况下:

  • 它从未调用set - 它假设它返回了足够大的东西而不必担心它。
  • 它假设Allocator::max_size()速度很慢,并尝试通过一次分配多个对象来优化它(allocate()旨在实现此目的,但我并不期望将相同的行为应用于容器像vectormap那样不使用连续的内存。基本上,它不是调用set,而是调用allocate(sizeof(T))来获取一个内存池,然后它可以在创建新对象时在内部重新分配。

这些假设几乎破坏了我在该项目中使用STL的尝试 - 我最终决定使用allocate(sizeof(T) * 20)容器。

答案 2 :(得分:0)

关于“了解这一点,为什么需要自定义分配器,它会改变什么?”

  • 自定义分配器可以优化小对象的分配
  • 优化具有通用尺寸的对象的分配
  • 挤出最后一位内存
  • ...

默认值只有一个策略(可能)。