【问题标题】:By how much does vector::resize increase capacity?vector::resize 增加了多少容量?
【发布时间】:2011-12-22 12:46:11
【问题描述】:

据我所知,当 vector::resize 需要增加时,C++ 标准并没有具体说明如何增加矢量容量。但是有“典型”的实现吗?

具体来说:我不知道我的向量需要多大。此外,元素以随机顺序出现。所以对于每个元素我都有这个:

if ( index >= vector.size() ) {
    vector.resize ( index + 1 );
}
vector.at ( index ) = element;

如果元素以递增的索引顺序出现,每次调用 resize 时向量容量是否会增加 1(在典型实现中)?我希望不会……

【问题讨论】:

  • @TomalakGeret'kal:这是一个不同的问题。重复的resize()s 没有保证的渐近线。
  • @KerrekSB:这完全是同一个问题。 “我的容器在实施中的容量会增加多少?”
  • @TomalakGeret'kal:不完全是:这个问题涉及push_back,并且push_back 具有强制性的复杂性保证(即摊销常数)——这反过来又迫使实现以几何方式增长存储。没有类似的要求会影响resize() 的情况。
  • @TomalakGeret'kal:我不确定 - 问题要求“实际乘数”,但我的意思是 resize() 和任何“乘数”之间没有联系,因为没有要求resize() 引起的分配遵循任何特定的方案。那是不同的背景,不是吗?

标签: c++ resize stdvector capacity


【解决方案1】:

该标准不保证重复调用resize() 的渐近性。容器将简单地将容量增加到所需的目标大小是完全可行的。事实上,这可能是resize() 的大多数标准用例中的理想 行为(即最不浪费的行为)(例如,它只使用一次)。

如果您担心,只需实现自己的几何增长:

if (index + 1 > v.size()
{
    if (v.capacity() < index + 1)
    {
        v.reserve(2 * (index + 1));   // I had 2 * capacity() here first, but
                                      // I think this version is better
    }
    v.resize(index + 1);
}

【讨论】:

  • 并且,在插入所有项目后,OP 可以再次缩小向量以节省内存,如果这是一个问题的话。
  • @arne: Not guaranteed.
  • @TomalakGeret'kal:v.resize(v.size()) 呢?我怀疑它不能保证减小尺寸,但它可以。
  • 我认为您几乎保证没有人会缩小尺寸,除了shrink_to_fit() 可能的例外,不是吗?
  • @TomalakGeret'kal:好的,我明白了。对于内存密集型应用程序,这绝对是需要牢记的事情......
【解决方案2】:

正如您所提到的,resize 的作用完全取决于您的实现(并且可能在同一实现的不同版本之间发生变化)。

在兼容的实现中,push_back 每次必须增加容量时都会导致容量翻倍,这与一系列push_back 的摊销复杂性有关。如果每次将容量增加1,则N添加的复杂度将是O(N^2),而如果push_back每次将容量增加一倍,同一系列添加的复杂度将仅为O(N) - 很重要。

至于您的问题 - 如果您事先知道最大 index,只需预先分配。否则,我认为您最好使用std::map

map<int, T> M;
for (...) {
  M[index] = element;
}

这对于N 添加将具有复杂性O(N log N),但不会在没有相应element 的索引上浪费内存。

【讨论】:

  • 注意容量不必加倍,任何严格大于1的常数都可以。
  • 除非你的 stroed 对象相当大,否则 map 会浪费更多的内存(每个 map 条目都有几个指针的开销,然后加上分配器的开销)。
猜你喜欢
  • 2011-07-11
  • 1970-01-01
  • 2020-11-15
  • 2012-07-28
  • 1970-01-01
  • 2020-09-22
  • 2019-05-22
相关资源
最近更新 更多