向量元素是否保证是连续的?

我的问题很简单: std::vector元素是否保证是连续的?换句话说,我可以使用指向 std::vector的第一个元素的指针作为 C 数组吗?

如果我没记错的话,C + + 标准并没有做出这样的保证。然而,std::vector的要求是这样的,如果元素不是连续的,几乎不可能满足这些要求。

有人能澄清一下吗?

例如:

std::vector<int> values;
// ... fill up values


if( !values.empty() )
{
int *array = &values[0];
for( int i = 0; i < values.size(); ++i )
{
int v = array[i];
// do something with 'v'
}
}
54794 次浏览

是的,std: : Vector 的元素保证是连续的。

该标准实际上确保了 vector在内存中是连续的,并且 &a[0]可以传递给需要数组的 C函数。

这个规则的例外是 vector<bool>,每个 bool只使用一个位,因此虽然它有连续的内存,但不能用作 bool*(这被广泛认为是一个错误的优化和错误)。

顺便说一下,你为什么不用迭代器呢? 这就是迭代器的作用。

Cplusplus.com:

矢量容器实现为动态数组; 就像常规数组一样,矢量容器的元素存储在连续的存储位置,这意味着不仅可以使用迭代器访问它们的元素,还可以使用指向元素的常规指针上的偏移量。

正如其他答案所指出的,向量的内容保证是连续的(除了布尔的古怪之外)。

我想添加的注释是,如果你对向量执行插入或删除操作,这可能会导致向量重新分配内存,那么你将导致所有保存的指针和迭代器失效。

这是从 C + + 98标准中遗漏的,但后来作为 TR 的一部分添加了。即将推出的 C + + 0x 标准当然会将此作为一项要求。

来自 n2798(C + + 0x 草案) :

23.2.6类模板向量[向量]

向量是一个支持随机访问迭代器的 Vector,此外,它还支持(分期) 定时插入和擦除操作在结束; 插入和擦除在中间采取线性时间。存储 管理是自动处理的,尽管可以给出提示以提高效率 矢量是连续存储的,这意味着如果 v 是一个矢量,其中 T 是其他类型的 那么对于所有0 < = n < v.size () ,它服从恒等式 & v [ n ] = = & v [0] + n。

正如其他人已经说过的,vector在内部使用一个连续的对象数组。当任何非常数成员函数被调用为 IIRC 时,指向该数组的指针应被视为无效。

然而,有一个例外! !

vector<bool>有一个专门的实现,旨在节省空间,使每个 bool 只使用一位。底层数组不是连续的 bool 数组,vector<bool>上的数组算法不像 vector<T>那样工作。

(我想这也有可能适用于任何矢量的专门化,因为我们总是可以实现一个新的。然而,std::vector<bool>是唯一一个简单的指针算法无法工作的标准专门化。)

我找到这个线程是因为我有一个用例,其中使用连续内存的向量是一个优势。

我正在学习如何在 OpenGL 中使用顶点缓冲对象。我创建了一个包装类来包含缓冲区逻辑,所以我需要做的就是传递一个浮点数组和一些配置值来创建缓冲区。 我希望能够从一个基于用户输入的函数生成一个缓冲区,所以长度在编译时是未知的。做这样的事情是最简单的解决办法:

void generate(std::vector<float> v)
{
float f = generate_next_float();
v.push_back(f);
}

现在我可以将向量的浮点数作为数组传递给 OpenGL 的缓冲区相关函数。这也消除了用 sizeof 来确定数组长度的需要。

这比分配一个巨大的数组来存储浮点数要好得多,并且希望我把它做得足够大,或者使用连续存储创建我自己的动态数组。