Before watching "C + + Primier", also solved in the sequential window Insert/erase will be involved in the problem of iterator failure, and did not delve into. I ran into this problem when I wrote the program today.
1 The inexplicable erase
Originally my program is purple, don't talk, I know this is a problem, but this is the most intuitive idea
Vector<int> A (arr,arr+sizeof (arr)/sizeof (*arr)); for (Auto it = A.begin (); it!= a.end (); ++it) {
if (*it) & 1) {
a.erase (it);
}
}
Yes, the program crashes. After the iterator it was removed, the IT iterator was invalidated and no more ++it operations were possible.
However, when I think erase do is just to move the elements of the It forward one position, why the iterator failed. I opened the "STL Source Analysis", SGI STL vector<t,alloc>::erase Source code is this:
Iterator Vector<t, alloc>::erase (iterator position)
{
if (position + 1!= end ())
copy (position + 1, fin ish, position);
--finish;
Destroy (finish);
return position;
}
As I thought, the erase function does not overwrite the input position iterator. I printed out the debug information and found that after erase, the _PTR member of the iterator, the value of the pointer, did not change, and the element that this pointer refers to is indeed the next element. So why is it ineffective?
I also checked the "C + + Primier", found that the standard writing on this book is this:
int arr[]={0,1,2,3,4,5,6,7,8,9,10};
Vector<int> A (arr,arr+sizeof (arr)/sizeof (*arr));
for (Auto it = A.begin (); it!= a.end ();) {
if (*it) &1) {
it=a.erase (it);
}
else
++it;
}
Run a bit, that's right. I printed the debug information and found that, as before, erase the results to the members of the It,it _ptr did not change. The only possibility is that there are other flags in the iterator and the iterator is "invalidated" if the current element is deleted. The C + + Primier does not explain this much, except that the erase function returns the iterator for the next element of the deleted element.
conclusion: In the STL, we cannot look at iterators as pointers, which are bound to memory, and iterators are bound to the elements in the container, and after deletion, the iterator is invalidated and cannot be accessed until it is assigned a value. 2 more carefully Ji -ji Insert
Wit, like me, will naturally explore how the iterator will look after the insert. So:
Vector<int> A;
for (int i = 0; i < ++i)
{
a.push_back (i);
}
for (Auto it = A.begin (); it!= a.end (); ++it) {
if (*it = 5) {
A.insert (it, 100);
++it
}
}
You know what..
Nothing happened. You may ask why you should ++it after inserting it. Before inserting, it points to 5, after inserting 100 before 5, it points to 100. So the next cycle, it will still point to 5. Trust me, your program will explode.
After I made a ++it, it points to 5, the next loop directly points to the element after 5, and completes the insert work smoothly.
World Peace ~ World Peace ~ I'm not so sure.
It suddenly occurred to me that the vector's capacity would increase when the insertion element was too high, and then it would be a problem. Do what you say:
Vector<int> A;
for (int i = 0; i < ++i)
{
a.push_back (i);
}
for (Auto it = A.begin (); it!= a.end (); ++it) {
if (*it = 5) {
A.insert (it
); ++it
}
}
BOOM. It really crashed. This means that the iterator after the insertion is invalid. What about before that.
I decided to test it roughly:
Vector<int> A;
for (int i = 0; i < ++i)
{
a.push_back (i);
}
Auto It1=a.begin ();
for (Auto it = it1; it!= a.end (); ++it) {
if (*it = 5) {
A.insert (it, MB); It=it1
}
}
After I insert it, direct it to the Begin () and step through it. After the execution of it=it1 still good, can go to perform ++it or collapse.
That is, all iterators fail after the capacity change. That's for sure. Capacity change, the container does more than just add capacity, because the container may not have enough memory behind it for us to use, so the container will have to reopen a large enough memory to store the elements in the container, and the current memory will be released. Thus, the iterator naturally fails. 3 Summary of C + + Primier
On the issue of container iterator invalidation, C + + Primier used a section of the summary, I translated into Chinese as follows:
(1) After adding elements to the container
For vectors and strings, if the container memory is reassigned, the iterators,pointers,references is invalidated, and if there is no reallocation, the iterator before the insertion point is valid and the iterator after the insertion point fails;
For Deque, the iterators,pointers,references fails if the insertion point is elsewhere except front and back, and the deque iterator fails when we insert the element to front and back. But reference and pointers are effective;
For list and forward_list, all iterator,pointer and refercnce are valid.
(2) After removing elements from the container
For vectors and strings, the iterators,pointers,references before the insertion point is valid; Off-the-end iterators are always invalidated;
For Deque, the iterators,pointers,references fails if the insertion point is elsewhere except front and back, and when we insert the element to front and back, the off-the-end fails, and the other iterators , pointers,references effective;
For list and forward_list, all iterator,pointer and refercnce are valid.
(3) Refresh the iterator in the loop
When working with Vector,string,deque, consider the problem that the iterator might fail when elements are added or removed in a loop. We must refresh the iterator.
int arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, ten};
Deque<int> V (arr,arr+sizeof (arr)/sizeof (*arr));
for (Auto it = V.begin (); it!= v.end ();)
{
if ((*it) & 1)
{
it = V.insert (it, *it);
it = 2;
}
else
it = v.erase (it);
}
As for it+=2, it is easy to explain that after the insert, it points to the newly added element, after +2, it points to the next element to be processed.
(4) Do not store off-the-end iterator in cyclic invariant
This is easy to understand, after adding or removing elements, off-the-end invalid, do not store words, every time from the end () function is taken from the latest off-the-end, naturally will not fail.
Finally:"C + + Primier" is a good book .