0

Let's say I have a std::vector<int> v which is filled with some numbers:

{0, 1, 2, 3}

Now, let's say I get an iterator pointing to the number 2 with v.begin()+2 and save it inside a variable. At this point if I insert another number between 1 and 2, and my vector will look like

{0, 1, 4, 2, 3}

does my iterator still pointing to the 2 (which has moved a cell forward) or it's pointing at the new number (4)? If so, is it possible to get a pointer which follows its element if it's moved?

EDIT:

Ok, my first question may have an answer, but I do not understand why it was marked as a duplicate since I asked something else too...

Xriuk
  • 429
  • 5
  • 16
  • 1
    No it does not. Insertion in vectors invalidates iterators. If it does it will be out of plain luck. – 101010 Oct 09 '15 at 14:01
  • @101010: Only if you forgot to `.reserve` space. Careful, `.reserve` probably will invalidate existing iterators as well. – MSalters Oct 09 '15 at 14:24

3 Answers3

4

Look at the documentation for the various containers; they specify how functions invalidate iterators.

http://en.cppreference.com/w/cpp/container/vector

std::vector::insert Causes reallocation if the new size() is greater than the old capacity(). If the new size() is greater than capacity(), all iterators and references are invalidated. Otherwise, only the iterators and references before the insertion point remain valid. The past-the-end iterator is also invalidated.

iAdjunct
  • 2,739
  • 1
  • 18
  • 27
2

It's guaranteed as far as no reallocation happens, which is the case if capacity() is greater or equal to the new size (so you can use reserve for this to happen).

If you need iterators to never be invalidated and follow your elements around you can consider using an std::list (which however has radically different complexity characteristics); whether this is acceptable depends on how you are actually using your vector.

Matteo Italia
  • 123,740
  • 17
  • 206
  • 299
0

If the reasons for not using iterators outweigh the reasons for using iterators, then don't use iterators.

There are containers in which iterators are necessary and/or better for their usual task. std::vector is not such a container. The main use of iterators in std::vector is to preserve the ability (which you'll almost never actually use) to change your mind later about the type of container.

Use an index (of type unsigned if you really care about x86-64 performance and you are really really sure that a container size over 4G elements is absurd. If you aren't giving it that much thought, use std::size_t. Do not make the beginner mistake of using int).

An index from 0 to size()-1 fits your specified requirement a lot better than an iterator from begin() through end()-1. Don't let style habits force you into writing bad code.

With std::vector and an index, you get more robust behavior than with an iterator and you can more easily understand what behavior to expect. It is still not the behavior you apparently would prefer. For that you need to decide whether you can live with the behavior you get or whether you need a different container.

JSF
  • 5,281
  • 1
  • 13
  • 20