How to update iterators after vectors redistribution

Here is the code snippet I was looking at:

vector<int> iv = {1,2,3,4,5,6,7,8,9,10}; auto iter = iv.begin(), mid = iv.begin() + iv.size()/2; for(int count = 100; count; --count ) { iter = iv.insert(iter, - 1); cout << "capacity = " << iv.capacity() << "*mid = " << *mid << endl; } 

In accordance with the iterator invalidation rules:
vector: all iterators and links to the insertion point are not affected if the new container size is larger than the previous capacity (in this case, all iterators and links are invalid) [23.2.4.3/1] Iterator invalidity rules

I understand that since I override the value of "iter" in each insert operation, perhaps I can keep it valid (please correct me if I am wrong). However, the middle iterator remains valid in this case, even if I do not fake it in the loop, as well as when changing the capacity of the vector.

So how can the middle be updated after redistribution?

To find out if the environment has changed at all or not, I changed line 4 in the code to:

 iv.insert(iter, -1); // Did not assign it back to iter. 

Printing the results of dereferencing a value in the middle implies a change and, possibly, also that iter is invalid. (Again, please correct me if I am wrong).

+5
source share
1 answer

Your understanding is correct. As capacity increases, any iterator becomes invalid. The mid iterator becomes invalid even when the capacity does not change, but basically points to the previous item.

Thus, the source code will work, at least for iter , however mid will become unusable on the first insertion. Upon modification, the code is completely invalid.

Usually the implementation of the vector tetra is just a simple pointer that points to some element for the backup array. Therefore, when changes in capacity and the array are redistributed, any such iterator no longer acts, since the pointer points to more invalid memory. As a result, you can see the garbage, you can get a segmentation error or accidentally see the correct values. When the capacity does not change, the elements in the array can move forward so that you can see the previous element in iterators after the insertion point, but only if there were no empty elements at the beginning of the array (for example, start was greater than zero). But they are all implementation-specific, and therefore the standard clearly indicates that most of the above are undefined behavior .

+3
source

Source: https://habr.com/ru/post/1246036/


All Articles