C++ std::vector元素保证是连续的吗?

C++ std::vector元素保证是连续的吗?,c++,vector,standards,C++,Vector,Standards,我的问题很简单:std::vector元素保证是连续的吗?换句话说,我可以使用指向std::vector的第一个元素的指针作为C数组吗 如果我的记忆力很好,C++标准就没有这样的保证。然而,std::vector需求是这样的,如果元素不是连续的,就几乎不可能满足它们 有人能澄清一下吗 例如: std::vector<int> values; // ... fill up values if( !values.empty() ) { int *array = &val

我的问题很简单: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'
    }
}
std::向量值;
// ... 填充值
如果(!values.empty())
{
int*数组=&值[0];
对于(int i=0;i
是的,std::vector的元素保证是连续的。

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

此规则的例外情况是
向量
,它每
bool
只使用一位,因此尽管它有连续内存,但不能用作
bool*
(这被广泛认为是错误的优化和错误)

顺便说一句,你为什么不使用迭代器呢?这就是他们的目的。

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


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


我想补充的一点是,如果你对向量进行插入或删除,这可能会导致向量重新分配内存,然后,您将导致所有保存的指针和迭代器无效。

这是C++98标准中遗漏的,但后来作为TR的一部分添加。即将发布的C++0x标准当然将包含这一要求

从n2798(C++0x的草稿):

23.2.6类模板向量[向量]

1向量是支持随机访问迭代器的序列容器。此外,它还支持(摊销) 在末尾执行固定时间插入和擦除操作;插入和擦除在中间取线性时间。存储 管理是自动处理的,尽管可以给出提示以提高效率。a的要素 向量是连续存储的,这意味着如果v是一个向量,T是另一种类型
然后,它服从标识&v[n]=&v[0]+n对于所有0,正如其他人已经说过的,
vector
在内部使用一个连续的对象数组。每当调用任何非常量成员函数IIRC时,指向该数组的指针都应视为无效

但是,有一个例外

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


(我想这也可能适用于向量的任何专业化,因为我们总是可以实现一个新的专业化。然而,
std::vector
是唯一的,呃,简单指针算法不起作用的标准专业化。)

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

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

void generate(std::vector<float> v)
{
  float f = generate_next_float();
  v.push_back(f);
}
void生成(std::vector v)
{
float f=生成下一个浮点数();
v、 推回(f);
}
现在我可以将向量的浮点值作为数组传递给OpenGL的缓冲区相关函数。这也消除了sizeof确定数组长度的需要


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

我知道,如果在
if
块中变异
,就会遇到麻烦。不过,我不知道你的问题的答案,所以我只留下一条评论。:)@格雷格:什么麻烦?你能详细说明一下吗?我想他的意思是推送新值可能会触发一个“realloc”,这会导致数组无效。对
值进行变异的调用,特别是改变其大小的调用(例如,
push_back()
),可能会提示重新分配基础向量,从而使复制到
数组中的指针无效。这与使用vector::iterator而不是指向向量的指针的原理相同。:)是的,我把``放在了值周围,试图弄清楚我说的是类本身,而不是其中包含的值。:)不幸的命名等等。我不认为这在一般情况下是一个问题,因为这个问题是相关的——为什么有人抓住一个指向内存的指针,然后开始处理向量而不是使用指针?这些元素仍然会存储在一个连续的内存块中,它只是在一个不同的地方。这个问题是关于连续性的。但是现有的指针和迭代器将无效。这一点很好。你应该在回答中说明你的意思。现在我知道为什么我的程序昨天出现了故障,当时我在一个双循环中删除了某些元素:)谢谢@user2891462:ISO 14882第二版第23.2.4节[lib.vector]中也有说明: