我的问题很简单: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'
}
}
答案 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*
(这被广泛认为是错误的优化和错误)。
答案 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)
Vector容器实现为动态数组;与常规数组一样,向量容器将其元素存储在连续的存储位置,这意味着它们的元素不仅可以使用迭代器访问,还可以使用常规指向元素的偏移量来访问。