可以假设STL向量存储总是连续的吗?

57
如果您有一个已经调整大小的STL向量,那么取第0个元素的地址并假设其余向量元素会相继出现在内存中是安全的吗?
例如:
vector<char> vc(100);
// do some stuff with vc
vc.resize(200);
char* p = &vc[0];
// do stuff with *p
6个回答

73

是的,这是一个有效的假设(*)。

根据C++03标准(23.2.4.1):

向量(vector)的元素是连续存储的,这意味着如果v是一个T类型(布尔类型除外)的向量,则对于所有0 <= n < v.size(),它遵循恒等式&v[n] == &v[0] + n。

(*)…但要注意,在向数组添加元素后,可能会重新分配数组(使任何指针和迭代器失效)。


1
如果你正在使用一份草案标准,或任何尚未批准和正式的内容,请明确说明。我在当前标准中没有找到类似的内容。 - David Thornley
5
在 C++0x 草案中,该内容位于 23.2.5.1,在 C++03 中则为 23.2.4.1。这个措辞在 C++98 标准中并不存在。我正在查看 ISO/IEC 14882:2003(E)。 - Eclipse
1
它是在技术勘误中后来添加的。 - Vadim Ferderer

27

C++03标准增加了规定,使得vector元素必须是连续的。

C++03 23.2.4段落1包含以下内容,而C++98标准文件中则没有:

vector的元素是连续存储的, 这意味着如果v是一个 vector<T, Allocator>,其中T 是除bool之外的某种类型,则对于所有 0 <= n < v.size(),它遵守身份 &v[n] == &v[0] + n

Herb Sutter在他的一篇博客文章《不要紧张:向量保证是连续的》中谈到了这个变化:

......连续性实际上是向量抽象的一部分。它是如此重要, 以至于当发现C++98标准没有完全保证连续性时, C++03标准被修改以明确添加保证。


+1:这就是答案。只有在符合2003标准的实现中才能安全地假设,而不是“总是”。 - Lightness Races in Orbit

14

存储器始终是连续的,但它可能会在向量的容量发生变化时移动。

如果你在容量变化操作之前有一个指针、引用或迭代器指向第零个元素(或任何元素),那么它将失效并需要重新分配。



4

std::vector 保证存储的项目在一个连续的数组中,因此是数组的首选替代品,也可用于与平台相关的低级代码(如 Win32 API 调用)进行接口交互。要获取指向数组的指针,请使用:

&myVector.front();

2

是的,这个问题与IT技术有关。

它应该始终是连续的。


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