繁体   English   中英

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

[英]Are std::vector elements guaranteed to be contiguous?

我的问题很简单: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'
    }
}

适当的C ++ 98标准缺少此功能,但后来将其添加为TR的一部分。 当然,即将到来的C ++ 0x标准将包含此要求。

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

23.2.6类模板向量[vector]

1向量是支持随机访问迭代器的序列容器。 另外,它在末尾支持(摊销)恒定时间插入和擦除操作。 在中间插入和擦除需要线性时间。 存储管理是自动处理的,尽管可以提供一些提示以提高效率。 向量的元素是连续存储的,这意味着如果v是向量,其中T是非bool的某种类型,则它对所有0 <= n <v都服从&v [n] ==&v [0] + n的标识。尺寸()​​。

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

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

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

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

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

正如其他人已经说过的, vector内部使用连续的对象数组。 每当将任何非常量成员函数称为IIRC时,应将该数组中的指针视为无效。

但是,有一个例外!

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

(我想向量的任何特殊化也可能是正确的,因为我们总是可以实现一个新的std::vector<bool> 。但是, std::vector<bool>是唯一的,错误的,标准的特殊化,简单指针运算将基于此进行。工作。)

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

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

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

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

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

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

cplusplus.com:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM