【C++】关于STL容器删除erase问题

对于容器vector、set

最近在看阿秀的八股文pdf时发现一条似乎有点问题,于是做了实验,以vector和set为例,这两个容器的erase函数都会返回下一个元素的迭代器,但是顺序容器vector确实不能使用erase(it++),此时it指向的并不是被删元素的下一个元素,具体可见下面的代码
在这里插入图片描述

#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;
}

输出结果如下:
第三行输出的时erase容器的返回迭代器所指向的元素,可以发现都是20,这个都没问题,但是vector的k却指向错误

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

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

本来以为失效后,这个迭代器应该指向一个未知数,结果指向的是30,后来又做了新的实验,把test01改为下面的代码:
k指向30,利用erase删除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);
}

结果如下

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

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

发现使用erase后k总会指向被删除元素的后面的后面的位置,此时指向的都是合法的位置,继续更改代码,将k指向30,再利用erase删除,test01代码如下:

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);
}

结果如下:

----------------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 

很奇怪,为什么还是指向最后一个数,继续++,再做实验,此时test01代码更改如下:

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);
}

结果如下:

----------------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 

总结:顺序容器使用erase之后后面的迭代器都会失效,所以在今后写代码时需要多注意下,而关联式容器只是被删除的元素的迭代器失效,后面的迭代器还是可以用的

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值