std :: vector元素是否保证是连续的?

时间:2009-05-11 17:38:05

标签: c++ vector standards

我的问题很简单:std :: vector元素是否保证是连续的?在order word中,我可以使用指向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'
    }
}

7 个答案:

答案 0 :(得分:98)

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

从n2798(C ++ 0x草案):

  

23.2.6类模板向量[向量]

     

1 vector是一个支持随机访问迭代器的序列容器。另外,它支持(摊销)   最后的恒定时间插入和擦除操作;在中间插入和擦除需要线性时间。存储   管理是自动处理的,但可以提供提示以提高效率。一个元素   向量是连续存储的,这意味着如果v是一个向量,其中T是某种类型的其他类型   对于所有0&lt; = n&lt;而不是bool,它遵循身份&amp; v [n] ==&amp; v [0] + n。 v.size()。

答案 1 :(得分:18)

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

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

答案 2 :(得分:7)

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

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

BTW,为什么不使用迭代器?这就是他们的目的。

答案 3 :(得分:5)

正如其他人已经说过的那样,vector内部使用了一个连续的对象数组。只要任何非const成员函数被称为IIRC,就应将指向该数组的指针视为无效。

然而,有一个例外!!

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

(我想也可能这对于vector的任何特化都可能是正确的,因为我们总是可以实现一个新的。但是,std::vector<bool>是唯一的,错误的标准特化,简单的指针算法赢了工作。)

答案 4 :(得分:3)

我找到了这个帖子,因为我有一个用例,其中使用连续内存的向量是一个优点。

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

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

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

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

答案 5 :(得分:2)

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

答案 6 :(得分:1)

cplusplus.com:

  

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