deque内存分配可以稀疏吗?

时间:2012-07-10 11:13:10

标签: c++ memory stl deque

deque的标准是否允许以稀疏的方式分配内存?

我的理解是deque的大多数实现都在内部以某种大小的块分配内存。我相信,虽然我不知道这个事实,但是这些实现分配了至少足够的块来存储当前大小的所有项目。因此,如果一个块是100个项目,那么

std::deque<int> foo;
foo.resize( 1010 );

您将获得至少11个分配的区块。但是鉴于在上面所有1010 int都是默认构造的,你真的需要在调整大小调用时分配块吗?你是否可以在某人实际以某种方式插入项目时分配给定的块。例如,实现可以将块标记为“所有默认构造”,并且在有人使用它之前不会分配它。

我问我有一种情况,我可能想要一个非常大的双端队列,在我最终使用的元素方面可能非常稀疏。显然我可以使用其他数据结构,比如地图,但我对deque的规​​则感兴趣。

给出resize void resize ( size_type sz, T c = T() );签名的相关问题是标准是否要求默认构造函数被正确调用sz次?如果答案是肯定的,那么我猜你至少对于具有非平凡构造函数的类型不能进行稀疏分配,尽管可能仍然可以用于内置类型,如int或double。

3 个答案:

答案 0 :(得分:3)

必须正确构建deque中的所有元素。如果你需要 一个稀疏的实现,我建议deque(或vector) 指针或Maybe类(你真的应该在你的工具箱中有一个) 无论如何)在有效之前不会构造类型。这不是 deque的作用。

答案 1 :(得分:3)

23.3.3.3声明deque::resize将附加sz - size()默认插入元素(szdeque::resize的第一个参数。)

默认插入(参见23.2.1/13)表示元素由表达式allocator_traits<Allocator>::construct(m, p)初始化(其中m是分配器,p是指向该类型的指针将被建造)。所以内存必须可用,元素将默认构造(初始化?)。

All-in-all:deque::resize如果想要符合要求,就不能对构造对象感到懒惰。您可以通过将惰性结构包装在boost::optional或任何其他Maybe容器中来轻松地将其添加到类型中。

答案 2 :(得分:0)

回答你的第二个问题。有趣的是,C ++ 03和C ++ 11之间存在差异。

使用C ++ 03,您的签名

void resize ( size_type sz, T c = T() );

将默认构造参数(除非您提供另一个值),然后从这个值复制构造新成员。

在C ++ 11中,此函数已被两个重载替换

void resize(size_type sz);

void resize(size_type sz, const T& c);

其中第一个默认构造(或值初始化)sz元素。