【发布时间】:2014-08-09 13:06:45
【问题描述】:
假设我在大小为“n”的std::vector<mytype> 的第“i”个位置插入了 p 个新元素。
由于std::vector 中的项目保证为其元素使用连续的存储位置,因此我似乎需要 4 个步骤来完成上述操作:
1) 如果空间不足,向量可能会重新分配,基本上是其大小的两倍。但这是一个恒定的时间操作(尽管非常大)。
2) 接下来是从旧向量到新向量的索引 0 到 i-1 的元素的 memcpy。
3) 然后你复制 'p' 个新项目被插入到第 i 个索引处。
4) 然后从旧向量到新向量的 i+1 到 n 个索引的所有项目的另一个 memcpy。
以上不都是常数时间运算吗?那么插入本身不应该是一个恒定的时间操作吗?那么为什么std::vector::insert 与插入的元素数量(复制/移动构造)加上定位后的元素数量(移动)成线性关系?
【问题讨论】:
-
重新分配成本应该随着大小而增加。
-
如果底层内存块没有被完全使用,则不需要重新分配,但是你应该将n个元素向左移动以插入新的元素。(这样就完成了通过
memcpy()并且,正如其他人所注意到的,它不是 O(1)。memcpy()ing 4KB 需要与 3MB 相同的时间?当然不会。) -
当然不是。
memcpy的成本与复制的数据量渐近成正比。 -
任何使用 memcpy 的 std::vector 实现都存在根本缺陷。它没有正确调用构造函数/析构函数和赋值运算符。
-
@Andrey Chernyakhovskiy:C++ 标准不要求向量类以任何特定方式管理其内存。它的作用是要求通过重复调用 push_back 创建一个 n 元素向量不超过 O(n) 时间。