1

Is the following an example of iterator invalidation?

int main() {
    std::vector<int> v = {1, 2, 3};
    auto it = v.begin();
    v.push_back(4);
    std::cout << *it << std::endl;
}

The code prints 0. I assume it's because the iterator has been invalidated? Is that correct?

cyrusbehr
  • 1,100
  • 1
  • 12
  • 32
  • 3
    Yes. All iterators and references (including the past-the-end iterator) are invalidated with [`std::vector::push_back`](https://en.cppreference.com/w/cpp/container/vector/push_back) if the new `size()` would be greater than `capacity()` – Drew Dormann Dec 09 '21 at 21:09
  • There we go. I was about to point out that some very kind souls aggregated the Iterator Invalidation Rules for all of the C++ Library containers in one spot, but πάντα ῥεῖ beat me to it. – user4581301 Dec 09 '21 at 21:18
  • And once it is invalidated, the value of the iterator when dereferenced is 0? – cyrusbehr Dec 09 '21 at 21:50
  • 1
    The value could be anything. Or nothing. You cannot reason in the general case about it because dereferencing an invalid iterator invokes [Undefined Behaviour](https://en.cppreference.com/w/cpp/language/ub). As you can probably guess from the name, the behaviour of a program with undefined behaviour is undefined. – user4581301 Dec 09 '21 at 22:26
  • It's true that a call of `push_back()` will only invalidate iterators for that vector if the capacity is changed. Can't rely on that though because the strategy for managing the capacity (e.g. when it grows, thereby invalidating iterators) is unspecified, and - in the real world - does vary between implementations. Unless you're going to check if a vector's capacity has changed everywhere, it is usually simpler to *assume* a call of `push_back()` invalidates iterators for that vector. – Peter Dec 10 '21 at 00:33

1 Answers1

3

From [vector.modifiers]/1 (C++-17 draft), which includes push_back

Causes reallocation if the new size is greater than the old capacity. Reallocation invalidates all the references, pointers, and iterators referring to the elements in the sequence. If no reallocation happens, all the iterators and references before the insertion point remain valid.

Thus, in your case, the capacity likely changes, and therefore the iterators are invalidated.

ChrisMM
  • 8,448
  • 13
  • 29
  • 48