c++ - 为什么 std::vector 不保留 "double"它的容量,而调整大小呢?

标签 c++ vector resize capacity

我刚刚发现 std::vector<T>::resize即使调整到比当前大小高出一个元素的大小,它的容量也会“翻倍”:

std::vector<int> v(50);
v.resize(51);
std::cout << v.capacity() << std::endl;

该程序在 GCC 和 Clang 中输出 100,在 Visual C++ 中输出 75。但是,当我从 resize 切换时至reserve :

std::vector<int> v(50);
v.reserve(51);
std::cout << v.capacity() << std::endl;

三个编译器的输出都是 51。

我想知道为什么实现对 resize 使用不同的扩展策略和 reserve .这似乎不一致,我希望这里有同样的行为。


我只是为我的问题添加一个链接,其中报告了对性能的影响: Why are C++ STL vectors 1000x slower when doing many reserves?


添加来自 C++11 标准的引用以阐明 reserve 的要求; §23.3.6.3(2):

After reserve(), capacity() is greater or equal to the argument of reserve if reallocation happens...


一些额外的想法:来自 C++11 标准:

Complexity: The complexity is linear in the number of elements inserted plus the distance to the end of the vector.

这实际上意味着在末尾插入单个元素的恒定(摊销)复杂性。但是,这仅适用于 vector 修饰符,例如 push_backinsert (§23.3.6.5)。

resize未在修饰符中列出。它列在 §23.3.6.3 vector容量部分。而且,resize 没有复杂性要求.

但是,在 vector概述部分(§23.3.6.1),写着:

it (vector) supports (amortized) constant time insert and erase operations at the end

问题是resize(size()+1)被认为是“最后插入”

最佳答案

据我所知,resizereserve 都不需要具有演示的行为。然而,两者都被允许这样的行为,尽管两者都可以分配确切的数量,并且就标准而言,两者都可以乘以先前的分配。

每种分配策略都有其优势。分配精确数量的优点是,当预先知道最大分配时,它没有内存开销。乘法的优点是它在与末端插入操作混合时保持不变的摊销属性。

测试实现选择的方法的优点是在调整大小时允许两种策略。要使用一种策略,可以保留然后调整大小。要使用另一个,只需调整大小。当然,必须意识到未指定的行为才能利用这一点。这种优势可能是也可能不是选择这些实现的原因。

人们可能会认为这是标准中规定的 vector API 的失败,即无法表达预期的重新分配行为(以标准保证的方式)。

关于c++ - 为什么 std::vector 不保留 "double"它的容量,而调整大小呢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48537812/

相关文章:

c++ - 如何从 switch 语句中排除浮点值?

r - 将向量与向量列表匹配

html - 如何防止在调整大小时更改父级的宽度

css - 从媒体查询、图标位置和字体大小的屏幕调整大小保持流动

c++ - 具有自动返回类型参数推导的可变参数模板

c# - 如何在 VS 2010 中创建 DirectShow 项目

c++ - 为了支持 move 语义,函数参数应该由 unique_ptr、value 还是 rvalue 获取?

java - Printable 打印尺寸不正确的 BufferedImage

c++ - 具有类类型左值操作数的条件表达式

c++ - LLDB C++调试