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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/849168/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 17:34:26  来源:igfitidea点击:

Are std::vector elements guaranteed to be contiguous?

c++vectorstandards

提问by Martin Cote

My question is simple: are std::vector elements guaranteed to be contiguous? In order word, can I use the pointer to the first element of a std::vector as a C-array?

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

If my memory serves me well, the C++ standard did not make such guarantee. However, the std::vector requirements were such that it was virtually impossible to meet them if the elements were not contiguous.

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

Can somebody clarify this?

有人可以澄清这一点吗?

Example:

例子:

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'
    }
}

回答by dirkgently

This was missed from C++98 standard proper but later added as part of a TR. The forthcoming C++0x standard will of course contain this as a requirement.

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

From n2798 (draft of C++0x):

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

23.2.6 Class template vector [vector]

1 A vector is a sequence container that supports random access iterators. In addition, it supports (amortized) constant time insert and erase operations at the end; insert and erase in the middle take linear time. Storage management is handled automatically, though hints can be given to improve efficiency. The elements of a vector are stored contiguously, meaning that if v is a vector where T is some type other than bool, then it obeys the identity &v[n] == &v[0] + n for all 0 <= n < v.size().

23.2.6 类模板向量[vector]

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

回答by Bill Lynch

As other answers have pointed out, the contents of a vector is guaranteed to be continuous (excepting bool's weirdness).

正如其他答案所指出的那样,向量的内容保证是连续的(除了 bool 的奇怪之处)。

The comment that I wanted to add, is that if you do an insertion or a deletion on the vector, which could cause the vector to reallocate it's memory, then you will cause all of your saved pointers and iterators to be invalidated.

我想补充的评论是,如果您对向量进行插入或删除操作,这可能会导致向量重新分配其内存,那么您将导致所有保存的指针和迭代器无效。

回答by Motti

The standard does in fact guarantee that a vectoris continuous in memory and that &a[0]can be passed to a Cfunction that expects an array.

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

The exception to this rule is vector<bool>which only uses one bit per boolthus although it does have continuous memory it can't be used as a bool*(this is widely considered to be a false optimization and a mistake).

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

BTW, why don't you use iterators? That's what they're for.

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

回答by Wuggy

As other's have already said, vectorinternally uses a contiguous array of objects. Pointers into that array should be treated as invalid whenever any non-const member function is called IIRC.

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

However, there is an exception!!

但是,有一个例外!!

vector<bool>has a specialised implementation designed to save space, so that each bool only uses one bit. The underlying array is not a contiguous array of bool and array arithmetic on vector<bool>doesn't work like vector<T>would.

vector<bool>有一个专门的实现来节省空间,所以每个 bool 只使用一位。底层数组不是一个连续的 bool 数组,并且数组算术vector<bool>不能像vector<T>那样工作。

(I suppose it's also possible that this may be true of any specialisation of vector, since we can always implement a new one. However, std::vector<bool>is the only, err, standard specialisation upon which simple pointer arithmetic won't work.)

(我想这也可能适用于向量的任何特化,因为我们总是可以实现一个新的特化。但是,这std::vector<bool>是唯一一个错误的标准特化,简单的指针算法不起作用。)

回答by NobodyImportant

I found this thread because I have a use case where vectors using contiguous memory is an advantage.

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

I am learning how to use vertex buffer objects in OpenGL. I created a wrapper class to contain the buffer logic, so all I need to do is pass an array of floats and a few config values to create the buffer. I want to be able to generate a buffer from a function based on user input, so the length is not known at compile time. Doing something like this would be the easiest solution:

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

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

Now I can pass the vector's floats as an array to OpenGL's buffer-related functions. This also removes the need for sizeof to determine the length of the array.

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

This is far better than allocating a huge array to store the floats and hoping I made it big enough, or making my own dynamic array with contiguous storage.

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

回答by Igor Oks

cplusplus.com:

cplusplus.com:

Vector containers are implemented as dynamic arrays; Just as regular arrays, vector containers have their elements stored in contiguous storage locations, which means that their elements can be accessed not only using iterators but also using offsets on regular pointers to elements.

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

回答by Beno?t

Yes, the elements of a std::vector are guaranteed to be contiguous.

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