C++ iterator failure and prevention

Serial container

Vector
array data structure: The elements of this data structure are allocated in contiguous memory. Insert and erase operations will cause the deletion point and the elements after the insertion point to move.
Therefore, the insertion point and the iterator after the deletion are all invalid , That is to say insert(*it) (or erase(*it)), and then in it++, it is meaningless.
Solution: The return value of erase(*it) is the value of the next valid iterator. it =cont.erase(it ); or it = vec.insert(it,0);

void vectorIter()
{
    
    
	vector<int> vec;
	for (int i = 0; i < 10; i++)
	{
    
    
		vec.push_back(i);//0,1,2,3,4,5,6,7,8,9
	}

	for (auto it = vec.begin(); it != vec.end(); it++)
	{
    
    
		if (*it == 5)
		{
    
    
			it =vec.erase(it);//删除5后迭代器指向6
			it = vec.insert(it,0);//插入0后迭代器指向0
			//直接erase或者insert会崩溃,因为迭代器失效了
		}
	}

	for (auto it = vec.begin(); it != vec.end(); it++)
	{
    
    
		cout << *it << endl;
	}

}

Two-linked list container

List
linked list data structure: For the list type data structure, a discontinuously allocated memory
delete operation is used to invalidate the iterator pointing to the deleted position , but it will not invalidate other iterators. There are two solutions, erase(*iter) will Return the value of the next valid iterator, or erase(iter++);
inserting data will not invalidate the iterator

void listIter()
{
    
    
	list<int> lst;
	for (int i = 0; i < 10; i++)
	{
    
    
		lst.push_back(i);//0,1,2,3,4,5,6,7,8,9
	}

	for (auto it = lst.begin(); it != lst.end(); it++)
	{
    
    
		if (*it == 5)
		{
    
    
			//it = lst.erase(it);//删除5后迭代器指向6
			lst.erase(it++);		//同上面一个效果
	
		}
	}

	for (auto it = lst.begin(); it != lst.end(); it++)
	{
    
    
		cout << *it << endl;
	}

}

Three associative containers

For map
related containers (such as map, set, multimap, multiset), deleting the current iterator will only invalidate the current iterator , as long as the current iterator is incremented when erasing . This is because containers such as map are implemented using red-black trees, and inserting or deleting a node will not affect other nodes.

void mapIter()
{
    
    
	map<int, int> map;
	for (int i = 0; i < 10; i++)
	{
    
    
		map[i] = i;
	}

	for (auto it = map.begin(); it != map.end(); it++)
	{
    
    
		if ((*it).first ==5)
		{
    
    
			//map.erase(it++);//同下方一样
			it =map.erase(it);		
		}
	}
}

Guess you like

Origin blog.csdn.net/GreedySnaker/article/details/114967640