[C++] About STL container delete erase problem

For container vector, set

Recently, when I was looking at the pdf of Axiu’s stereotyped essay, I found that there seemed to be a problem, so I did an experiment, taking vector and set as examples, the erase function of these two containers will return the iterator of the next element, but the sequence container vector does not Use erase (it++), at this time it does not point to the next element of the deleted element, see the following code for details
insert image description here

#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <iostream>
using namespace std;


#include <vector>
#include <set>

void printSet(set<int>& s)
{
    
    
	for (set<int>::iterator it = s.begin(); it != s.end(); it++)
	{
    
    
		cout << *it << " ";
	}
	cout << endl;
}

//插入和删除
void test02()
{
    
    

	set<int> s1;
	//插入
	s1.insert(10);
	s1.insert(30);
	s1.insert(20);
	s1.insert(40);
	printSet(s1);

	//删除
	auto k = s1.begin();
	auto k1 = s1.erase(k++);
	cout << *k << endl;
	cout << *k1 << endl;
	printSet(s1);


	//清空
	//s1.erase(s1.begin(), s1.end());
	s1.clear();
	printSet(s1);
}

void printVector(vector<int>& v) {
    
    

	for (vector<int>::iterator it = v.begin(); it != v.end(); it++) {
    
    
		cout << *it << " ";
	}
	cout << endl;
}

//插入和删除
void test01()
{
    
    
	vector<int> v1;
	//尾插
	v1.push_back(10);
	v1.push_back(20);
	v1.push_back(30);
	v1.push_back(40);
	printVector(v1);

	//删除
	auto k = v1.begin();
	auto k1=v1.erase(k++);
	cout << *k << endl;
	cout << *k1 << endl;
	printVector(v1);

	//清空
	v1.erase(v1.begin(), v1.end());
	v1.clear();
	printVector(v1);
}

int main() {
    
    
	cout << endl;
	cout << "----------------Vector--------------" << endl;
	test01();
	cout << "----------------Set--------------" << endl;

	test02();


	system("pause");

	return 0;
}

The output results are as follows:
when the third line is output, the elements pointed to by the iterator returned by the erase container can be found to be 20, which is all right, but the k of the vector points to an error

----------------Vector--------------
10 20 30 40 
30
20
20 30 40 

----------------Set--------------
10 20 30 40 
20
20
20 30 40 

I thought that after the failure, the iterator should point to an unknown number, but it turned out to be 30. Later, I did a new experiment and changed test01 to the following code: k points to 30, and use erase to delete the value of
30

void test01()
{
    
    
	vector<int> v1;
	//尾插
	v1.push_back(10);
	v1.push_back(20);
	v1.push_back(30);
	v1.push_back(40);
	printVector(v1);

	//删除
	auto k = v1.begin();
	k++;
	auto k1=v1.erase(k++);
	cout << *k << endl;
	cout << *k1 << endl;
	printVector(v1);

	//清空
	v1.erase(v1.begin(), v1.end());
	v1.clear();
	printVector(v1);
}

The result is as follows

----------------Vector--------------
10 20 30 40 
40
30
10 30 40 

----------------Set--------------
10 20 30 40 
20
20
20 30 40 

It is found that after using erase, k will always point to the position behind the deleted element. At this time, it points to a legal position. Continue to change the code, point k to 30, and then use erase to delete. The code of test01 is as follows:

void test01()
{
    
    
	vector<int> v1;
	//尾插
	v1.push_back(10);
	v1.push_back(20);
	v1.push_back(30);
	v1.push_back(40);
	printVector(v1);

	//删除
	auto k = v1.begin();
	k++;
	k++;
	cout << "before erase k=" << *k << endl;
	auto k1=v1.erase(k++);
	cout << "after erase k=" << *k << endl;
	cout << *k1 << endl;
	printVector(v1);

	//清空
	v1.erase(v1.begin(), v1.end());
	v1.clear();
	printVector(v1);
}

The result is as follows:

----------------Vector--------------
10 20 30 40 
before erase k=30
after erase k=40
40
10 20 40 

----------------Set--------------
10 20 30 40 
20
20
20 30 40 

It's very strange, why it still points to the last number, continue to ++, and do the experiment again. At this time, the code of test01 is changed as follows:

void test01()
{
    
    
	vector<int> v1;
	//尾插
	v1.push_back(10);
	v1.push_back(20);
	v1.push_back(30);
	v1.push_back(40);
	printVector(v1);

	//删除
	auto k = v1.begin();
	k++;
	k++;
	k++;
	cout << "before erase k=" << *k << endl;
	auto k1=v1.erase(k++);
	cout << "after erase k=" << *k << endl;
	cout << *k1 << endl;
	printVector(v1);

	//清空
	v1.erase(v1.begin(), v1.end());
	v1.clear();
	printVector(v1);
}

The result is as follows:

----------------Vector--------------
10 20 30 40 
before erase k=40
after erase k=0
40
10 20 30 

----------------Set--------------
10 20 30 40 
20
20
20 30 40 

Summary: After the sequential container uses erase, the subsequent iterators will be invalid, so you need to pay more attention when writing code in the future, while the associative container only invalidates the iterator of the deleted element, and the subsequent iterators can still be used

Guess you like

Origin blog.csdn.net/qq_43050258/article/details/129994053