2

I'd like to use a vector of iterators to link to the contents of a vector< int>.
When I try to fill said vector of iterators via a single iterator "it" I get a segmentation fault when I try to dereference it.

vector <int> vec;
vector <int>::iterator it = vec.begin();
vector<vector <int>::iterator> vecIt(3);
vec.push_back(1);    
vec.push_back(2);
vec.push_back(3);
vecIt[0] = it;

cout << *vecIt[0] << endl; //this line causes seg. fault

However, if I do not use my "it" iterator, it works just fine:

vector <int> vec;
vector<vector <int>::iterator> vecIt(3);
vec.push_back(1);  
vec.push_back(2);
vec.push_back(3);
vecIt[0] = vec.begin();

cout << *vecIt[0] << endl;

Could someone explain this behavior to me? What causes the seg. fault when using an extra iterator?
Also, is there a better way of going through my vector< int> and saving iterators (or pointers, if that is more advisable) to the vector of iterators?

hsvar
  • 127
  • 4
  • 12

2 Answers2

4

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

If the new size() is greater than capacity() then all iterators and references (including the past-the-end iterator) are invalidated. Otherwise only the past-the-end iterator is invalidated.

Thus, by taking the iterator (it's an empty vector, too) and then making the vector's size exceed its capacity by calling push_back(), you are invalidating that iterator. However, when you do push_back() and then take the iterator, no invalidation occurs as the vector's size does not exceed its capacity.

user2296177
  • 2,725
  • 1
  • 11
  • 21
  • Thank you! I moved the line initializing "it" to after the push-backs and it works perfectly now. – hsvar Jun 20 '16 at 20:28
3

When you push a new element via

vec.push_back(1);

The iterators get invalidated. See e.g. at cplusplus:

If a reallocation happens, all iterators, pointers and references related to the container are invalidated. Otherwise, only the end iterator is invalidated, and all iterators, pointers and references to elements are guaranteed to keep referring to the same elements they were referring to before the call.

463035818_is_not_a_number
  • 64,173
  • 8
  • 58
  • 126