STL container delete element, iterator is invalid

  1. Type:
  • Standard STL sequence container : vector, string, deque and list.
  • Standard STL associative containers : set, multiset, map and multimap.
  • Non-standard sequence container slist and rope. Slist is a singly linked list, rope is essentially a heavy string
  • Non-standard associative containers hash_set, hash_multiset, hash_map and hash_multimap.
  • Several standard non-STL containers , including array, bitset, valarray, stack, queue and priority_queue

      It is worth noting that arrays can work with STL algorithms, because pointers can be used as array iterators.

  2. Delete elements
If you want to delete something, remember to add erase after the remove algorithm
The so-called delete algorithm, in the end, you must call a member function to delete an element, but because remove does not know which container it is currently acting on, the remove algorithm cannot really delete an element.
1.Vector
 
vector<int> v;   
v.reserve(10);   
for (int i = 1; i <= 10; ++i) {
 v.push_back(i);
}
cout << v.size();   // 10
v[3] = v[5] = v[9] = 99; 
remove(v.begin(), v.end(), 99); 
//v.erase(remove(v.begin(),v.end(),99),v.end());
cout << v.size();   // 10!

2. list
list<int> listTest;
listTest.remove(99);//This member function will really delete elements and is more efficient than erase+remove
The difference between remove and remove_if is very similar. But unique behaves like remove. It is used to delete things (adjacent duplicate values) from an interval without accessing the container holding the interval elements. If you really want to delete an element from the container, you must also call unique and erase in pairs. Unique is also similar to remove in the list. Just like list::remove really deletes things (and much more efficient than the erase-remove idiom). list::unique also really deletes adjacent duplicate values ​​(also more efficient than erase-unique).
 
Three iterator failure:
 
A question asked by a netizen:
void   main() 
{ 
vector <string> vcs; 
vcs.push_back( "this   is   A "); 
vector <string   > ::iterator   it=vcs.begin(); 
int   i=9; 
for(;it!=vcs.end();++it) 
{ 
cout < < "caplity   of   vector   is   :   " < <vcs.size() < <endl; 

cout < < "---> " < <*it < <endl;   //去掉此句会有一个超过vector 
                                   //大小的循环,高手能解释一下为什么? 
if(i==9) 
{ 
vcs.push_back( "this   is   BBBBB "); 
cout < < "vcs.push! " < <endl; 
} 
i=8; 
} 
}
典型的迭代器失效.

 
vector:
1. When an element is inserted (push_back), the iterator returned by the end operation must be invalid.
2. When an element is inserted (push_back), the return value of capacity is changed from before the element is not inserted, and the entire container needs to be reloaded. At this time, the iterators returned by the first and end operations will become invalid.
3. When the delete operation (erase, pop_back) is performed, all iterators pointing to the delete point will be invalidated; the iterators pointing to the element behind the delete point will also be invalidated.
Failure conditions of deque iterators:
1. Inserting elements at the head or tail of the deque container will not invalidate any iterator.
2. Deleting elements at the head or tail will only invalidate the iterator pointing to the deleted element.
3. Insertion and deletion in any other position of the deque container will invalidate all iterators pointing to the container element.
List/set/map
1. When deleting, the iterator pointing to the deleted node becomes invalid
list<int> intList; 
list<int>::iterator it = intList.begin(); 
while(it != intList.end()) 
{ 
it = intList.erase(it); 
…… 
}


Four. Choosing the time <transfer>-summarize the characteristics of various containers
(1) Vector
internal data structure: array.
Random access to each element, the time required is constant.
The time required to add or delete elements at the end has nothing to do with the number of elements, and the time required to add or delete elements in the middle or at the beginning varies linearly with the number of elements.
Elements can be dynamically increased or decreased, and memory management is done automatically, but programmers can use the reserve() member function to manage memory.
The vector's iterator will fail when the memory is reallocated (the element it points to is no longer the same before and after the operation). When more than capacity()-size() elements are inserted into the vector, the memory will be reallocated and all iterators will be invalid; otherwise, the iterators pointing to any element after the current element will be invalid. When an element is deleted, the iterator to any element after the deleted element will be invalidated.

(2) Deque
internal data structure: array.
Random access to each element, the time required is constant.
The time required to add elements at the beginning and end has nothing to do with the number of elements, and the time required to add or delete elements in the middle varies linearly with the number of elements.
Elements can be dynamically increased or decreased, memory management is automatically completed, and member functions for memory management are not provided.
Adding any element will invalidate the deque's iterator. Removing elements in the middle of the deque will invalidate the iterator. When an element is deleted at the head or tail of the deque, only the iterator to that element becomes invalid.

(3) List
internal data structure: two-way circular linked list.
One element cannot be randomly accessed.
It can be traversed in both directions.
The time required to add or delete elements at the beginning, end and anywhere in between is constant.
Elements can be dynamically increased or decreased, and memory management is automatically completed.
Adding any element will not invalidate the iterator. When deleting an element, except for the iterator pointing to the currently deleted element, other iterators will not be invalidated.

(4)
Internal data structure of slist : singly linked list.
It cannot be traversed in both directions, only from front to back.
Other features are similar to list.

(5)
Stack adapter, which can convert any type of sequence container into a stack, generally using deque as a supported sequence container.
Elements can only be last in first out (LIFO).
You cannot traverse the entire stack.

(6) The queue
adapter, which can convert any type of sequence container into a queue, generally uses deque as the supported sequence container.
Elements can only be first in first out (FIFO).
Cannot traverse the entire queue.

(7) Priority_queue
adapter, which can convert any type of sequence container into a priority queue, generally using vector as the underlying storage method.
Only the first element can be accessed, not the entire priority_queue.
The first element is always the one with the highest priority.

(8) The set
key and value are equal.
The key is unique.
The elements are sorted in ascending order by default.
If the element pointed to by the iterator is deleted, the iterator becomes invalid. Any other operations that add or delete elements will not invalidate the iterator.

(9) The multiset
key may not be unique.
Other features are the same as set.

(10) Hash_set is
compared with set. The elements in it are not necessarily sorted, but are distributed according to the hash function used, which can provide faster search speed (of course, related to the hash function).
Other features are the same as set.

(11) The hash_multiset
key may not be unique.
Other features are the same as hash_set.

(12) The map
key is unique.
The elements are arranged in ascending order by default.
If the element pointed to by the iterator is deleted, the iterator becomes invalid. Any other operations that add or delete elements will not invalidate the iterator.

(13) The multimap
key may not be unique.
Other features are the same as map.

(14) Hash_map is
compared with map. The elements in it are not necessarily sorted by key value, but are distributed according to the hash function used, which can provide faster search speed (of course also related to the hash function).
Other features are the same as map.

(15) The hash_multimap
key may not be unique.
Other features are the same as hash_map.

Guess you like

Origin blog.csdn.net/panpanloveruth/article/details/7018549