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

发布于 2024-07-19 18:35:25 字数 479 浏览 5 评论 0原文

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

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

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.

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

听你说爱我 2024-07-26 18:35:25

C++98 标准本身遗漏了这一点,但后来作为 TR 的一部分添加了。 即将推出的 C++0x 标准当然会将此作为要求。

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

23.2.6 类模板向量[vector]

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

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.

From n2798 (draft of 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().

白鸥掠海 2024-07-26 18:35:25

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

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

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

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.

淡淡的优雅 2024-07-26 18:35:25

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

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

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

The standard does in fact guarantee that a vector is continuous in memory and that &a[0] can be passed to a C function that expects an array.

The exception to this rule is vector<bool> which only uses one bit per bool thus 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).

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

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

不过,有一个例外!!

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

(我想这也可能适用于向量的任何专门化,因为我们总是可以实现一个新的。但是,std::vector是唯一的、错误的、标准的专门化简单的指针算术将无法工作。)

As other's have already said, vector internally uses a contiguous array of objects. Pointers into that array should be treated as invalid whenever any non-const member function is called 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.

(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.)

瞳孔里扚悲伤 2024-07-26 18:35:25

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

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

沩ん囻菔务 2024-07-26 18:35:25

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

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

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

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

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

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:

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.

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.

dawn曙光 2024-07-26 18:35:25

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文