STL之vector使用注意点(迭代器失效,clear不回收空间,巧用swap函数)

本文探讨了C++中vector容器在插入和删除操作时导致迭代器失效的问题,分析了失效原因并提供了避免策略。通过使用reserve方法预分配空间来减少扩容引发的迭代器失效,同时介绍了erase方法返回的有效迭代器以及swap函数在内存管理和容量调整中的应用,如释放多余容量和保持迭代器有效。

迭代器失效问题

vector容器在插入(发生扩充)和删除的过程中可能会有迭代器失效的问题,我们在使用的时候需要注意这个问题。

先了解一下插入的时候为什么迭代器会失效

在这里插入图片描述

原因

在发生扩充的时候,原迭代器指向的还是原来空间的位置

上代码

/*------------------------------------------------------------------------
	*1.
	*插入时发生扩充,会新开辟一块空间,不一定和原来的空间相同,造成迭代器失效
	---------------------------------------------------------------------------*/
	vector<int> v;
	auto b1 = v.begin(); //0x00A9F758
	cout << &b1 << endl;
	v.push_back(1);
	auto b2 = v.begin(); //0x0A9F744
	cout << &b2 << endl;

避免

reserve的作用是更改vector的容量(capacity),使vector至少可以容纳n个元素。
如果n大于vector当前的容量,reserve会对vector进行扩容。其他情况下都不会重新分配vector的存储空间

删除的时候为什么迭代器会失效

这是因为vetor,deque使用了连续分配的内存,删除一个元素导致后面所有的元素会向前移动一个位置。

代码分析

/*----------------------------------------------------------------------------
	*2.
	* 删除时发生迭代器失效
	---------------------------------------------------------------------------------*/
	vector<int> v2{1,2,3,4};
	auto b3 = v2.begin();
	cout << &b3 << endl; //原来迭代器的位置
	auto b4 = v2.erase(v2.begin());//删除第二个元素

	/*
	*在vs2013下陷入阻塞状态,b3迭代器已经失效
	*/
	/*
	for (b3; b3 < v2.end(); b3++)
	{
		cout << *b3 << " ";
	}
	*/

	/*
	*接受erase返回的指针 ,可以正常使用
	*/
	for (b4; b4 < v2.end(); b4++)
	{
		cout << *b4 << " ";
	}
	cout << &b4 << endl;

解决

erase方法可以返回下一个有效的iterator。

swap函数一般用法

swap用来交换连个容器的值

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

	vector<int>v1;
	for (int i = 0; i < 10; i++)
	{
		v1.push_back(i);
	} 
	printVector(v1);

	vector<int>v2;
	for (int i = 10; i > 0; i--)
	{
		v2.push_back(i);
	} 
	printVector(v2);
	
	//互换容器
	cout << "互换后" << endl;
	v1.swap(v2);
	printVector(v1);
	printVector(v2);

swap函数clear()之后的内存回收

在使用clear函数之后,容器的内容被清空,但是容量还没被回收掉,借助swap构建一个临时容器与他交换实现回收空间

/*
	* swap函数的巧用 
	* 用clear()无法保证内存回收。 使用swap函数
	*创建一个局部容器 容量为0 进行交换
	*/

	v5.clear();//内容清空了
	cout << v5.capacity();//但是容量还在,并没有回收掉

	{
		vector<int> tmp;
		tmp.swap(v5);
	}//使用{} 是为了将 tmp析构掉

	cout << v5.size() << endl;//0
	cout << v5.capacity() << endl;//0

swap函数把多余的容量给释放掉

比如我为了避免多次申请空间而使用reserve函数一次性申请10000个空间,但是我存了了100个元素,造成了浪费,这个时候就可以使用swap在不修改原内容的情况下把多余的容量给释放掉

	/*----------------------------------------------------------------------------
	*3.
	* 提前分配好空间,减少vector在动态扩展容量时的扩展次数
	---------------------------------------------------------------------------------*/
	vector<int> v5;
	//预留空间
	v5.reserve(100000);

	for (int i = 0; i < 100; i++) {
		v5.push_back(i);
		
	}
	cout << v5.size() << endl;//100 这是因为 我放了100个元素
	cout << v5.capacity() << endl;//100000 //容量为100000

	/*
	* swap函数的巧用 
	* 使用swap把多余的容量给释放掉 有多少元素 就占多大的容量
	*/
	vector<int> (v5).swap(v5);
	cout << v5.size() << endl;//100
	cout << v5.capacity() << endl;//100
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值