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

时间:2016-03-30 05:53:17

标签: c++ c++11 stl iterator

以下是我正在查看的代码段:

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;

}

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

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

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

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

iv.insert(iter, -1); // Did not assign it back to iter.

在中间打印取消引用该值的结果表示该更改,也可能是该消息无效。 (如果我错了,请再次纠正我。)

1 个答案:

答案 0 :(得分:3)

您的理解是正确的。一旦容量增加,任何迭代器都将变为无效。 mid迭代器即使在容量没有变化时变得无效,但它基本上指向前一个元素。

因此原始代码至少可以用于iter,但mid在首次插入时将无法使用。通过修改,代码完全无效。

通常vector迭代器的实现只是一个指向某个元素到支持数组的简单指针。因此,当容量更改并重新分配数组时,任何此类迭代器都不再有效,因为指针指向不再有效的内存。因此,您可能会看到垃圾,您可能会出现分段错误或随机查看正确的值。当容量没有改变时,数组中的元素可以向前移动,这样你就可以在插入点之后看到迭代器中的前一个元素,但仅在数组开头没有空元素的情况下(例如{{1}大于零)。但所有这些都是具体的实施,因此标准明确规定上述大多数是未定义的行为