std::vector::reserve 是不是重新分配内部数组?

Posted

技术标签:

【中文标题】std::vector::reserve 是不是重新分配内部数组?【英文标题】:Does std::vector::reserve reallocate the internal array?std::vector::reserve 是否重新分配内部数组? 【发布时间】:2012-03-04 14:36:49 【问题描述】:

我有一个函数,它接受int * 并修改传入的数组。我提前知道它将访问多少个元素。假设这是m 值。

如果我在 vector<int> 上调用 reserve(m) 然后将指针 data() 发送到函数会发生什么?

我的猜测是,如果我随后从指针访问数据,就好像它是一个数组一样,那么这样做 可能 工作,但是如果我尝试使用 @ 从向量中检索这些数据987654326@ 向量的大小不会更新,我会有问题。所以我应该只使用resize(m) 来做到这一点。

【问题讨论】:

你能给我们看一些代码而不是解释代码的作用吗? 我会说你的猜测是正确的,只需使用resize 为什么你想这样做? 是的,使用 resize()。你为什么还要问这个,你看到 resize() 有什么缺点吗? data() 不是std::vector(2003 标准)的一部分 【参考方案1】:

不要这样做;这是未定义的行为,根本不允许。相反,您应该执行几乎同样昂贵的resize() 操作,然后传递data() 指针。

唯一增加的成本来自内存的归零。不幸的是,没有标准库容器可以处理 未初始化 动态存储,而不是 std::unique_ptr<int[]>(new int[m])。不过,归零的成本非常小(但它在概念上可能很烦人,因为您知道您将覆盖数据)。我想在高性能环境中,您可以尝试使用唯一指针方法。 (请注意,基本类型的数组-new[] 通常完全等同于::operator new()malloc())。

【讨论】:

【参考方案2】:

正确,空向量上的reserve(m) 只是保证下一个 m push_back() 不会触发重新分配。向量的大小仍将保持为 0,并且禁止写入分配的数据。

这里调用resize(m)是正确的方法。

【讨论】:

【参考方案3】:
void reserve ( size_type n );

只有在当前容量小于n时才重新分配内部数组。

【讨论】:

【参考方案4】:

reserve 改变了容器的内部大小(因此capacity() 现在更大了),但数组的size 没有增长(size() 保持与调用之前相同)。因此,要直接回答您的问题,,它使向量的capacity 至少为n,其中n 是您提供给reserve 的参数。

如果capacity 足够大(但size 更小),当您调用data() 时(或执行@ 987654333@) 并通过该指针访问数组。只要您在向量中使用 POD 类型并且在写入它们之前不读取它们,我认为这不会是未定义的行为。但是不要尝试使用类类型,因为向量的 size 之外的元素将未初始化,并且使用它们是 UB。

这样做是没有意义的,因为当你尝试push_back 向量上的某些东西或调用resize 来实际更新大小时,它会覆盖你颠覆性地写入向量的值。只需使用resize 或使用vector(int) 构造函数来设置构造大小。

【讨论】:

它应该是未定义的。 size() 之后的那些元素不会被初始化。 @James 他说他正在使用vector<int> (POD),所以只要他在写入值之前不读取值,他应该没问题,不是吗? 不,我们说的是未调整大小的向量。无论存储的模板类型如何,引用(读取或写入)向量末尾之外的任何元素都是未定义的。 (有效地解除对 end() + n 的引用,其中 n >= 0。)虽然它可能“有效”,但这绝对不是一个好习惯。 @James 我认为不好的做法和未定义的行为不是一回事。这是否是一种好的做法是相当明显的(不是),但我认为这不会使它成为未定义的行为。 老实说,刚刚花了最后 20 分钟浏览 C++ 标准,我不知道它是否未定义。我的直觉仍然认为它是,或者如果不是,它应该是。访问向量内存的唯一方法是通过&*,它创建一个指针,显然如果您知道内存是有效的,那么递增和取消引用该指针就不是未定义的。然而,事实上它是通过取消引用迭代器获得的指针,这里有一个略带灰色的区域:( &*begin() ) + n 不是未定义的,但&*( begin() + n ) 是(其中 n >= size() 和 n

以上是关于std::vector::reserve 是不是重新分配内部数组?的主要内容,如果未能解决你的问题,请参考以下文章

std::vector::resize() 与 std::vector::reserve()

libxx.so: undefined reference, vector.reserve(n)

libxx.so: undefined reference, vector.reserve(n)

libxx.so: undefined reference, vector.reserve(n)

std::vector 保留和调整 NUMA 局部性

为未知大小的 cv::Mat 保留向量内存