迭代器如何在向量重新分配后更新

Sat*_*rat 5 c++ iterator stl c++11

这是我正在查看的代码片段:

vector<int> iv = {1,2,3,4,5,6,7,8,9,10};
auto iter = iv.begin(), mid = iv.begin() + iv.size()/2;
for(int count = 100; count; --count ) {
    iter = iv.insert(iter, - 1);
    cout << "capacity = " << iv.capacity() << "*mid = " << *mid << endl;

}
Run Code Online (Sandbox Code Playgroud)

根据迭代器失效规则:
vector:插入点之前的所有迭代器和引用都不受影响,除非新容器大小大于先前容量(在这种情况下所有迭代器和引用都无效)[23.2.4.3/1] 迭代器失效规则

我明白,因为我在每次插入操作中重新分配"iter"的值,或许我能够保持它的有效性(如果我错了,请纠正我).但是,迭代器"mid"在这种情况下仍然有效,即使我没有在循环中篡改它,也当向量的容量发生变化时.

那么,"mid"在重新分配后如何能够自我更新?

要知道mid是否完全改变,我将代码中的第4行更改为:

iv.insert(iter, -1); // Did not assign it back to iter.
Run Code Online (Sandbox Code Playgroud)

打印在中间取消引用该值的结果表明该更改,并且可能也表明它已失效.(如果我错了,请再次纠正我).

Zby*_*000 3

你的理解是正确的。一旦容量增加,任何迭代器都会失效。mid即使容量没有改变,迭代器也会变得无效,但它基本上指向前一个元素。

因此,原始代码至少可以工作iter,但是mid在第一次插入时将变得不可用。修改后代码完全无效。

通常迭代器的实现vector只是一个简单的指针,指向支持数组的某个元素。因此,当容量发生变化并且重新分配数组时,任何此类迭代器都不再有效,因为指针指向不再有效的内存。因此,您可能会看到垃圾、可能出现分段错误或随机看到正确的值。当容量不变时,数组中的元素可能会向前移动,以便您可以在插入点之后看到迭代器中的前一个元素,但前提是数组开头没有空元素(例如start大于零)。但所有这些都是特定于实现的,因此标准明确规定上述大部分是未定义的行为