2

I try to set vector of pointers to int to elements of another vector

vector<int> vecInt;
vector<int*> vecPInt;
int main()
{
    vecInt.push_back(1);
    vecPInt.push_back(&vecInt[0]);
    vecInt.push_back(1);
    vecPInt.push_back(&vecInt[1]);
    for(auto v:vecInt)
    {
        cout<<v<<"\n";
    }
    for(auto v:vecPInt)
    {
       cout<<*v<<"\n";
    }

}

but the result is

1

1

11717664

1

There are another way to do this. But why in this case this is the behaviour?

Vladimir Yanakiev
  • 860
  • 10
  • 21

2 Answers2

5

The second time you push back an element into the vector vecInt, the capacity of the vector changes. New area of twice the size is allocated and hence the old pointer starts pointing to something else. Basically, whenever the size of the vector reaches its capacity, reallocation of the vector has to happen and it invalidates all pointers referring to the elements in the sequence.
Have a look at When does a std::vector reallocate its memory array?

Community
  • 1
  • 1
nishantsingh
  • 4,017
  • 4
  • 21
  • 44
  • 1
    Another useful link: http://stackoverflow.com/questions/6438086/iterator-invalidation-rules – Fabio says Reinstate Monica Sep 20 '16 at 10:27
  • 1
    To the questioner: To avoid this problem, use something else like `list` or `deque` instead of `vector`, those two do not invalidate iterators on `push_back` (IIRC). However, this whole design seems a little strange. Are you really sure you need to store these pointers? – Aaron McDaid Sep 20 '16 at 10:32
3

I agree with the other answer. It is undefined behaviour to access the address, as you may be accessing address which may have been most likely vacated

Use vector::reserve, the problem will be gone as all the time, the address will remain unchanged. Demo

Saurav Sahu
  • 9,755
  • 5
  • 42
  • 64