Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do STL iterators guarantee validity after collection was changed?

Let's say I have some kind of collection and I obtained an iterator for the beginning of it. Now let's say I modified the collection. Can I still use the iterator safely, regardless of the type of the collection or the iterator?

To avoid confusion, here is the order of operations I talk about:

  1. Get an iterator of the collection.
  2. Modify the collection (obviously not an element in it, but the collection itself).
  3. Use the iterator obtained at step 1. Is it stil valid according to STL standard?!
like image 737
user88637 Avatar asked Jul 25 '10 16:07

user88637


People also ask

Is iterator valid after erase?

Every iterator and reference after the point of erasing is invalidated. Only the iterators and references to the erased element is invalidated.

What invalidates an iterator?

An Iterator becomes invalidate when the container it points to changes its shape internally i.e. move elements from one location to another and the initial iterator still points to old invalid location. Iterator invalidation in vector happens when, An element is inserted to vector at any location.

How do I know if my iterator is invalid?

use erase with increment : if (something) l. erase(itd++); so you can test the validity of the iterator.

Does std :: move invalidate iterators?

For reference, std::vector::swap does not invalidate iterators.


1 Answers

Depends on the container. e.g. if it's a vector, after modifying the container all iterators can be invalidated. However, if it's a list, the iterators irrelevant to the modified place will remain valid.

  • A vector's iterators are invalidated when its memory is reallocated. Additionally, inserting or deleting an element in the middle of a vector invalidates all iterators that point to elements following the insertion or deletion point. It follows that you can prevent a vector's iterators from being invalidated if you use reserve() to preallocate as much memory as the vector will ever use, and if all insertions and deletions are at the vector's end. [1]

  • The semantics of iterator invalidation for deque is as follows. Insert (including push_front and push_back) invalidates all iterators that refer to a deque. Erase in the middle of a deque invalidates all iterators that refer to the deque. Erase at the beginning or end of a deque (including pop_front and pop_back) invalidates an iterator only if it points to the erased element. [2]

  • Lists have the important property that insertion and splicing do not invalidate iterators to list elements, and that even removal invalidates only the iterators that point to the elements that are removed. [3]

  • Map has the important property that inserting a new element into a map does not invalidate iterators that point to existing elements. Erasing an element from a map also does not invalidate any iterators, except, of course, for iterators that actually point to the element that is being erased. [4] (same for set, multiset and multimap)

like image 122
kennytm Avatar answered Sep 19 '22 10:09

kennytm