在使用reserve之后,使用std::vector::data。

18

我有一个std::vector,在它上面调用reserve时传入了一个很大的值。之后我检索data()

由于迭代data会导致崩溃,我想知道这样做是否被允许。 reserve是否强制更新data以适应分配的内存范围?


3
为什么使用reserve而不是resizereserve只分配内存,resize会在其中构造对象。 - n. m.
5
可以让我们看看你的代码吗? - rocambille
3
重新调整大小可能非常昂贵。使用保留操作可以确保您稍后可以插入对象。 - Humam Helfawi
1
请注意,即使data()是有效的并且向量末尾之外分配了内存,您仍然不能保证允许访问该内存。例如,vector实现可能正在使用该内存进行簿记或其他用途。 - user1084944
1
这个问题:https://dev59.com/Q18e5IYBdhLWcg3wucf-,讨论了在空向量上调用data()会发生什么。(您的向量是空的,因为reserve()不会改变大小。)似乎有些实现会返回nullptr。 - Winston Ewert
4个回答

17

reserve的保证是后续插入不会重新分配,因此不会导致失效。就是这样。没有其他的保证。


这个保证对于一个空向量成立吗? - Christophe

14

reserve是否强制更新分配的内存范围中的data

不是。标准只保证std::vector::data返回指针,并且[data(), data() + size())是一个有效的范围,而capacity并不相关。

§23.3.11.4/1 vector data [vector.data]:

返回:这样一个指针,以使[data(), data() + size())是一个有效的范围。对于非空向量,data() == addressof(front())


4

对于空向量 (size() == 0),即使其容量不为零,data() 并没有要求返回可解引用的指针。它可能返回 nullptr 或者一些任意的值(唯一的要求是该值能与自身比较,并且 0 可以被添加到该值上而不会触发未定义行为)。


1
我会说文档在这个话题上非常清晰:在data() + size()之后的任何内容都可以被分配,但不是初始化的内存:如果您想要初始化此内存,您应该使用vector::resize

void reserve (size_type n);

请求更改容量

请求向量容量至少足以包含n个元素。

如果n大于当前向量容量,则函数会导致容器重新分配其存储空间,将其容量增加到n(或更大)。

在所有其他情况下,函数调用不会导致重新分配,并且向量容量不受影响。

此函数对向量大小没有影响,也不能修改其元素。

我不确定为什么你会想要在 reserve() 后访问 data() + size() 之后的任何内容: reserve() 的预期使用是在你知道或可以估计容器的预期大小时,避免不必要的重新分配内存,同时避免不必要的内存初始化(例如,初始化所需的数据不可用可能会导致效率低下或不切实际)。在这种情况下,你可以将 log(N) 次重新分配和复制替换为只有1次,从而提高性能。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接