【问题标题】:Iterator validity for std::vector<std::vector<T>>std::vector<std::vector<T>> 的迭代器有效性
【发布时间】:2015-08-08 10:39:05
【问题描述】:

在我的代码中,主要的数据结构是

std::vector<std::vector<T>> Worldlines ;

在我的一个子例程中,我删除元素并将元素(可能导致容器重新分配以具有更多容量)添加到其中一个组件(比如说Worldlines[i])。

如果我在向量Worldlines[i] 中有一些T,我将其位置保存为std::vector&lt;T&gt;::iterator 对象,如果重新分配Worldlines[i],它们通常可能会失效。

如果使用 j != i 指向属于 Worldlines[j]T 的迭代器呢?它们是否保证仍然有效,或者其中一个向量的重新分配可能会导致其他向量的重新分配,因为它们被绑定在一个向量向量中?

谢谢大家。

【问题讨论】:

  • 我编辑了这个问题以避免不同类型的迭代器之间的混淆。

标签: c++ vector stl iterator


【解决方案1】:

外部向量的所有迭代器,包括指向元素Worldlines[i]的迭代器都是有效的。您只需更改迭代器指向的对象的值,该值对应于元素 Worldlines[i] 的位置。该向量未重新分配,因为没有对向量进行任何需要重新分配的操作。

除了元素Worldlines[i]本身的迭代器可能被重新分配的元素之外,向量的所有元素的迭代器也是有效的。

你可以想象这样的情况,比如你有一个指针数组(实际上一个向量向量是一个动态分配的指针数组)。如果您更改了数组元素的某个指针的值,则数组本身不会重新分配,并且更改的元素在数组中仍然具有相同的索引。:)

【讨论】:

  • @Vinay Shukla 还有什么?
  • 我猜“向量的所有元素的迭代器”是指 Worldlines[j] 元素的所有迭代器,其中 j != i。
  • @Adriano Angelone 我希望我写得很清楚。:) 忘记向量的值类型。你可以想象像 std::vector 这样的向量。如果您更改了向量的某个元素的类型 T 的值,则向量本身并没有改变:既没有添加也没有删除任何元素。所以向量的所有迭代器都是有效的。
  • 你写的很清楚,实际上我没有:)我实际上担心的是 Worldlines[j] 内的 T 的迭代器,而不是向量本身的迭代器。
  • @Adriano Angelone 如果对向量 Worldlines[j] 应用了某些操作,可能会导致其元素的重新分配,则其迭代器无效。
【解决方案2】:

它们将保持有效。

即使 vector 被重新分配,同一容器中的其他向量也不受影响。

基本上,您可以将矢量图像实现为:

struct Vector {
    T * begin_of_memory;
    int number_of_allocated_elements;
    int number_of_used_elements;
};

而迭代器只是T*

当需要调整向量的大小以便为新元素腾出空间时,begin_of_memory 当然会发生变化,并且当前位于该区域中间的任何迭代器都将不再可用。

但是Vector结构本身只是改变了它的内容,指向它的指针仍然有效。

【讨论】:

  • 我想这是因为stackoverflow.com/questions/19504455/…stackoverflow.com/questions/10898007/… 中显示的参数。我只是想非常确定。谢谢。
  • 标准是这样说的(23.3.6.5):如果没有发生重新分配,则插入点之前的所有迭代器和引用仍然有效。
  • @VinayShukla 这与这里有什么关系? “当向量需要调整大小时”意味着发生了重新分配。
  • std::vector&lt;std::vector&lt;T&gt;&gt; 中,重新分配内部向量之一可能会导致其他向量也被重新分配,或者它们完全独立?
  • @AdrianoAngelone:他们是独立的。在 C++ 中,每个对象在内存中都有固定大小...可变大小的容器将其内容保存在其他区域,而不是对象本身内部。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-04-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-01
  • 2018-02-02
相关资源
最近更新 更多