std::vector 向下调整大小

Posted

技术标签:

【中文标题】std::vector 向下调整大小【英文标题】:std::vector resize downward 【发布时间】:2010-11-12 10:40:42 【问题描述】:

C++ 标准似乎没有说明两者对容量的副作用 resize(n)n < size()clear()

它确实声明了push_backpop_back 的摊销成本 - O(1)

我可以设想一种实现通常的容量变化 ala CLRS 算法(例如,放大时加倍,缩小时减半size to < capacity()/4)。 (Cormen Lieserson Rivest Stein)

谁有任何实施限制的参考?

【问题讨论】:

【参考方案1】:

以较小的大小调用resize()vector 的容量没有影响。它不会释放内存。

vector 释放内存的标准习惯用法是使用空的临时swap() swap()std::vector<T>().swap(vec);。如果要向下调整大小,则需要从原始向量复制到新的本地临时向量,然后将生成的向量与原始向量交换。

更新:C++11为此添加了成员​​函数shrink_to_fit(),将capacity()减少为size()是一个非绑定请求。

【讨论】:

按照我的阅读方式,他询问的是对内存使用的影响——他特别询问了调整大小对容量的影响。该标准没有指定这种情况下的结果,但我能想到的唯一原因是希望释放未使用的内存。使用临时技巧进行交换是实现此目的的惯用方式。 标准确实通过不为这些操作指定容量()的减少来指定结果。因此它不能减少。 在某些环境中,在初始“构造”阶段之后禁止分配或释放内存。只要可以确定向量在操作期间不会尝试分配或释放内存,向量就可以在这种环境中使用。所以这个问题在这种情况下是相关的(把我带到这里)。 使用 g++ 和 libstdc++ 10:std::vector::shrink_to_fit 进行新的分配。 myvector.data() 每次调用 shrink_to_fit() 时都会产生不同的地址【参考方案2】:

实际上,标准确实规定了应该发生的情况:

这是来自vector,但所有容器的主题都是相同的(listdeque 等...)

23.2.4.2 向量容量[lib.vector.capacity]

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

6) 效果:

if (sz > size())
    insert(end(), sz-size(), c);
else if (sz < size())
    erase(begin()+sz, end());
else
    ; //do nothing

也就是说:如果指定给resize的大小小于元素个数,这些元素将从容器中删除。关于capacity(),这取决于erase() 对它做了什么。

我无法在标准中找到它,但我很确定 clear() 被定义为:

void clear()

    erase(begin(), end());

因此,clear()capacity() 的影响也与erase() 对其的影响有关。按标准:

23.2.4.3 矢量修饰符 [lib.vector.modifiers]

iterator erase(iterator position);
iterator erase(iterator first, iterator last);

4) 复杂度:T的析构函数被调用的次数等于被擦除元素的次数......

这意味着元素将被销毁,但内存将保持不变。 erase() 对容量没有影响,因此resize()clear() 也没有影响。

【讨论】:

resize向下现在记录为等效于一系列pop_back()调用,而不是erase。这是否消除了容量不会改变的保证? (见***.com/q/19941601/103167)【参考方案3】:

容量永远不会减少。我不确定标准是否明确说明了这一点,但这是暗示的:如果n &lt; capacity()resize(n) 不能使迭代器和对向量元素的引用无效。

【讨论】:

【参考方案4】:

当我检查 gcc (mingw) 时,释放向量容量的唯一方法是 mattnewport 所说的。 将其与其他临时向量交换。 此代码适用于 gcc。

template<typename C> void shrinkContainer(C &container) 
    if (container.size() != container.capacity()) 
        C tmp = container;
        swap(container, tmp);
    
    //container.size() == container.capacity()

【讨论】:

以上是关于std::vector 向下调整大小的主要内容,如果未能解决你的问题,请参考以下文章

如何在调整大小的 std::vector 的最后一个元素之后插入?

如何调整 Eigen::MatrixXd 的 std::vector 的大小

如何在不丢失现有数据的情况下调整 std::vector 的大小?

调整 std::vector<std::unique_ptr<T>> 大小的性能

调整动态字符串数组的大小[关闭]

如何调整 std::vector<std::queue<std::unique_ptr<int>>> 的大小?