std::vector 向下调整大小
Posted
技术标签:
【中文标题】std::vector 向下调整大小【英文标题】:std::vector resize downward 【发布时间】:2010-11-12 10:40:42 【问题描述】:C++ 标准似乎没有说明两者对容量的副作用
resize(n)
、n < size()
或 clear()
。
它确实声明了push_back
和pop_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
,但所有容器的主题都是相同的(list
、deque
等...)
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 < 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 的大小?