【问题标题】:How to completely manage heap memory allocation of std containers like map?如何完全管理像map这样的std容器的堆内存分配?
【发布时间】:2013-07-20 08:06:20
【问题描述】:

我对使用多个 std map 很感兴趣,我希望它们都从一个公共内存池中分配元素。根据我目前阅读的内容,我可以使用自定义分配器(例如 Boost pool_alloc)来实现这一点。

我的问题是,尽管使用 Boost pool_alloc 之类的东西来管理元素本身的分配,std map 是否仍会使用少量堆内存作为某种形式的容器开销,而不是由 boost pool_alloc 管理?关于使用 std map 本身,我正在考虑指向元素的指针?

【问题讨论】:

  • 您要的是一个包含指针的容器吗?抱歉问了,但到目前为止我还没有明白...
  • @Stefan:不,不是包含指针的容器。鉴于自定义分配器将负责元素本身的分配,我问 std::map 的所有容器内存开销是否也将由自定义分配器覆盖。我希望这有助于澄清我的问题
  • 好的。明白了。不。特定分配器负责在堆上为特定元素分配空间,而不是为容器本身分配空间。如果你想改变,你需要为你的特定容器重载 operator new/delete。

标签: c++ dictionary heap-memory std memory-pool


【解决方案1】:

简短版

一种地图类型,例如:

typedef std::map<
    int,
    int,
    less<int>,
    boost::pool_allocator<pair<const int, int> >
    > 
    AMapType;

将使用 boost::pool_allocators 完成它需要的所有分配。一些初始结构很可能是在堆栈上创建的。多少以及确切的结构将取决于实现。

分配器重新绑定

以上可以通过使用allocator::rebind实现

所有符合 std::allocator 的分配器(例如 boost::pool_allocator)都提供了一个 rebind 模板结构,格式如下:

template<class U> struct rebind{
   typedef AllocatorType<U> other;
};

这可用于为不同类型获取相同类型的分配器:

typedef AllocatorOfOther AllocatorType::rebind<ADifferentType>::other;

gcc std::map 内部结构

g++ std::map 实现(我检查了 4.7.3 和 4.1.1)完全由单个节点类型构建。这包括键值对以及 rbTree 结构所需的指针和颜色位。为了分配它,它使用来自用户提供的分配器的重新绑定结构定义了一个节点分配器。这用于随着地图的增长而进行的所有分配。每个新节点都在一次分配中分配。

标准

我检查了 C++11 标准,但找不到任何指定应如何分配此类结构的内容。要么我没有找到正确的部分,要么没有指定。不过,不使用给定分配器类型的用户似乎有点毫无意义。

【讨论】:

  • 只是想澄清一下:据我了解,重新绑定将元素 T 转换为某种 Node,带有额外的左右指针(或类似的东西)。这是否意味着,除了 Node 元素(由 rebind 生成)本身之外,std::map 不会创建其他分配?
  • 所以,我做了你所做的,但我使用了boost::pool_allocator&lt; int &gt;。这奏效了。这怎么能行?
  • @JHBonarius 很可能容器实现实际上从未将分配器用于其原始类型,并且总是首先将其重新绑定到其他类型。在那种情况下,模板参数中的几乎任何类型都可以工作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-04-03
  • 2010-11-15
  • 2013-01-13
  • 1970-01-01
  • 2021-11-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多