vector容器,resize/reserve/assign总结

本文详细介绍了C++标准库中vector的属性和成员方法,包括capacity、size和max_size。重点讲解了resize()、reserve()和assign()的用途和区别。resize()用于改变容器大小,resize()在容量不足时会扩容;reserve()用于预分配空间,避免多次扩容带来的性能损失;assign()则用于替换容器内容。文中通过实例展示了这三个方法的使用场景和效果,帮助理解它们在实际编程中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

参考 《std::vector》

vector属性

  • capacity
    返回当前存储空间能够容纳的元素数
  • size
    返回容器中的元素数,即 std::distance(begin(), end())
  • max_size
    此值通常反映容器大小上的理论极限,即理论上可申请到的最大容量大小。

vector成员方法

  • reserve( n )
    增加 vector 的容量到大于或等于 n 的大小。
    若 n > capacity() ,则扩容。分配新存储,并将原空间元素拷贝到新空间内
    若 n < capacity() ,缩容?,NO,该方法不做任何事

  • resize( count )
    重设容器大小以容纳 count 个元素。

    • 若 count < size ,则减小容器元素(从尾部删除)到 count 个,
    • 若 count > size ,则容器增加若干个元素,直至size == count
  • assign( . . )
    替换容器的内容。主要有三种方式

    1. assign( size_type count, const T& value ); 替换为 count个value
    2. assign( InputIt first, InputIt last ); 替换为迭代中指向的内容
    3. assign( std::initializer_list ilist ); 来自 initializer_list ilist 的元素替换内容

vector使用默认方式实例化产生的对象为空对象。

	vector<int> vec;
	if (vec.empty())		// 容器为空
	{
		cout << "The current size is :" << vec.size()  << "\n"
			<< "The available space is: " << vec.capacity() << endl;
	}
有关vector::reserve()的使用

reserve()一般用作预分配容器大小,类似于数组操作的 int arr[10] 预先申请10个空间,但此时空间内的元素并没有使用。而我们之后使用 push_back() 等操作时,才会对容器内的空间进行使用。

使用场景:
vector容器是一种不定长(自增)的顺序表,原理是在我们使用时预先分配一定的空间比如10,当我们使用超过10个时,容器内部进行扩容(1.5倍或2倍扩容),扩容后容器容量为20,那么下一次扩容为40,…80 … 160 。 而每一次的扩容都需要将之前旧空间内的数据拷贝到新的空间内,会产生一定的开销。

而如果我们预先知道我们将使用到多大空间时,就可以使用reserve()一次扩容到足够的空间,节省了许多不必要的操作消耗。

下面这个小程序就测试了,10000个数据vector需要扩容24次,容量达到 12138 。

#include <iostream>
#include <vector>

using namespace std;


int main()
{
	vector<int> vec;

	int* ptr = vec.data();	// 0x00000000
	int cnt = 0;

	int num = 10000;			// 测试 1万个数据,vector需要扩容几次
	while (num--)
	{
		vec.push_back(num);
		if (ptr != vec.data())	// 保存数据的首地址不同,即发生了扩容,更换了保存数据的空间位置
		{
			cnt++;
			ptr = vec.data();
		}
	}
	cout << "cnt = " << cnt << endl;	// cnt = 24

	return 0;
}

当我们修改程序,添加vec.reserve(10000); // 预先分配 10000 个空间 这样一条语句时,程序的执行结果将会是 cnt = 0 size = 10000 。

下面是对vec.reserve() 使用的测试,当我们增大扩容时,将会按照我们期望的那样操作,而当我们进行减少扩容时,此语句将会被忽略。

#include <iostream>
#include <vector>

using namespace std;


int main()
{
	// vector使用默认方式实例化产生的对象为空对象。
	vector<int> vec;
	if (vec.empty())		// 容器为空
	{
		cout << "The current size is :" << vec.size() << "\n"
			<< "The available space is: " << vec.capacity() << "\n"
			<< "------------------------" << endl;
	}




	vec.reserve(10);			// 预分配容器空间,10个

	cout << "The current size is :" << vec.size() << "\n"		// 当前的元素个数
		<< "The available space is: " << vec.capacity() << "\n";	// 当前的容量大小
	for (auto const& v : vec) cout << v << " ";						// 当前的元素内容					
	cout << "\n------------------------" << endl;





	vec.reserve(5);			// 预分配空间减少到 5个, 此语句无效

	cout << "The current size is :" << vec.size() << "\n"
		<< "The available space is: " << vec.capacity() << "\n";
	for (auto const& v : vec) cout << v << " ";
	cout << "\n------------------------" << endl;


	return 0;
}

/* 
输出:
		The current size is : 0
		The available space is: 0
		------------------------
		The current size is : 0
		The available space is: 10

		------------------------
		The current size is : 0
		The available space is: 10

		------------------------

*/
有关vector::resize()的使用

resize()一般用作改变容器内现有元素的数量,有时候也可以充当初始化的手段使用。

  1. 使用vector::resize(),申请的元素默认值为0 。(当申请的元素个数 > 容器容量时,扩容)
	vec.resize(5);			// 申请5个元素,初始化为0	

	cout << "The current size is :" << vec.size() << "\n"		// 当前的元素个数
		<< "The available space is: " << vec.capacity() << "\n";	// 当前的容量大小
	for (auto const& v : vec) cout << v << " ";						// 当前的元素内容					
	cout << "\n------------------------" << endl;
	/*
	输出:
		The current size is :5
		The available space is: 5
		0 0 0 0 0
		------------------------
*/
  1. 使用vector::resize(),申请的元素,可以指定初始化的值。
    使用指定初始化的申请元素时,如果是增加元素,将会保留原来的元素,对新增加的元素设置初值
	// vec = {0 0 0 0 0};
	int a = 5;
	vec.resize(10,a);			// 申请10个元素,初始化为指定的变量 a	

	cout << "The current size is :" << vec.size() << "\n"
		<< "The available space is: " << vec.capacity() << "\n";
	for (auto const& v : vec) cout << v << " ";
	cout << "\n------------------------" << endl;
	/*
	输出:
		The current size is :10
		The available space is: 10
		0 0 0 0 0 5 5 5 5 5
		------------------------
*/
  1. 使用vector::resize(),申请的元素,可以指定初始化的值。
    使用指定初始化的申请元素时,如果是减少元素,则该初值无用。
    具体操作过程为,从尾部开始删除元素,直至容器内元素达到要求实际上只是修改了size属性的值
    且,减少元素的过程不会改变容器的容量
	// vec = {0 0 0 0 0 5 5 5 5 5};
	vec.resize(3, a);			// 申请10个元素,初始化为指定的变量 a	

	cout << "The current size is :" << vec.size() << "\n"
		<< "The available space is: " << vec.capacity() << "\n";
	for (auto const& v : vec) cout << v << " ";
	cout << "\n------------------------" << endl;
	/*
	输出:
		The current size is :3
		The available space is: 10
		0 0 0
		------------------------
*/

测试代码:

#include <iostream>
#include <vector>

using namespace std;

int main()
{
	vector<int> vec;
	if (vec.empty())		// 容器为空
	{
		cout << "The current size is :" << vec.size() << "\n"
			<< "The available space is: " << vec.capacity() << "\n"
			<< "------------------------" << endl;
	}




	vec.resize(5);			// 申请5个元素,初始化为0	

	cout << "The current size is :" << vec.size() << "\n"		// 当前的元素个数
		<< "The available space is: " << vec.capacity() << "\n";	// 当前的容量大小
	for (auto const& v : vec) cout << v << " ";						// 当前的元素内容					
	cout << "\n------------------------" << endl;





	int a = 5;
	vec.resize(10, a);			// 申请10个元素,初始化为指定的变量 a	

	cout << "The current size is :" << vec.size() << "\n"
		<< "The available space is: " << vec.capacity() << "\n";
	for (auto const& v : vec) cout << v << " ";
	cout << "\n------------------------" << endl;





	vec.resize(3, a);			// 申请10个元素,初始化为指定的变量 a	

	cout << "The current size is :" << vec.size() << "\n"
		<< "The available space is: " << vec.capacity() << "\n";
	for (auto const& v : vec) cout << v << " ";
	cout << "\n------------------------" << endl;




	vec.clear();			// 清理所有元素	

	cout << "The current size is :" << vec.size() << "\n"
		<< "The available space is: " << vec.capacity() << "\n";
	for (auto const& v : vec) cout << v << " ";
	cout << "\n------------------------" << endl;


	/*
	输出:
		The current size is :0
		The available space is: 0
		------------------------
		The current size is :5
		The available space is: 5
		0 0 0 0 0
		------------------------
		The current size is :10
		The available space is: 10
		0 0 0 0 0 5 5 5 5 5
		------------------------
		The current size is :3
		The available space is: 10
		0 0 0
		------------------------
		The current size is :0
		The available space is: 10

		------------------------
	*/
	return 0;
}
vector::reserve() 与 vector::resize() 容易被混淆,这里简单列举一下两者区别
  • 首先,resize()是在我们使用容器时,进行操作的,如果容器的容量不足够我们使用,我们需要扩容。因此resize()应该具有扩容的功能
  • 而,reserve()是在我们使用容器前,进行操作的,我们需要预估容器的使用规模,从而预先分配足以容纳这些数据的容量。

下面是几个简单的例子,有助于了解具体过程。ps:vec.data()不同,表示进行了扩容。

int main()
{
	vector<int> vec;

	vec.reserve(100);	// 预分配100个空间的容量
	vec.resize(50);	// 增加50个值为0的元素
	cout << vec.size() << "  " << vec.capacity() << " " << (void*)vec.data() << endl;
	cout << "--------------------" << endl;


	// resize()
	// 重新申请150个元素,如果申请的数量超过空间容量,将重新分配空间

	vec.resize(100);		// 申请100个元素,不扩容
	cout << vec.size() << "  " << vec.capacity() << " " << (void*)vec.data() << endl;
	vec.resize(300);		// 申请300个元素, 扩容
	cout << vec.size() << "  " << vec.capacity() << " " << (void*)vec.data() << endl;
	cout << "--------------------" << endl;


	// reserve(n) 
	// 设置容器空间的尺寸/容量,如果 n 大于当前容量,将扩容,申请新的空间
	//							如果 n 小于当前容量,无需改变空间位置

	vec.reserve(50);		// 缩小容量,此语句将不会生效
	cout << vec.size() << "  " << vec.capacity() << " " << (void*)vec.data() << endl;
	vec.reserve(500);		// 扩容,申请一片可以容纳500个元素的空间,将原空间元素拷贝至新的空间
	cout << vec.size() << "  " << vec.capacity() << " " << (void*)vec.data() << endl;

	/*
	输出:
		50  100 013CEA50
		--------------------
		100  100 013CEA50
		300  300 013D1C58
		--------------------
		300  300 013D1C58
		300  500 013D2138
	*/
}
有关vector::assign()的使用

assign给出的定义是替换容器的内容。其中在它的第一中使用方式与resize()非常相似。见下示例:

int main()
{
	vector<int> vec1, vec2;

	vec1.assign(10, 1);

	cout << "The current size is :" << vec1.size() << "\n"		// 当前的元素个数
		<< "The available space is: " << vec1.capacity() << "\n";	// 当前的容量大小
	for (auto const& v : vec1) cout << v << " ";						// 当前的元素内容					
	cout << "\n------------------------" << endl;

	vec2.resize(10, 1);

	cout << "The current size is :" << vec2.size() << "\n"		// 当前的元素个数
		<< "The available space is: " << vec2.capacity() << "\n";	// 当前的容量大小
	for (auto const& v : vec2) cout << v << " ";						// 当前的元素内容					
	cout << "\n------------------------" << endl;

	/*
	输出:
		The current size is :10
		The available space is: 10
		1 1 1 1 1 1 1 1 1 1
		------------------------
		The current size is :10
		The available space is: 10
		1 1 1 1 1 1 1 1 1 1
		------------------------
*/

	return 0;
}

下面通过一个测试搞清楚这两个函数的区别。
这里再次强调一下两个函数的更能定义:

  • resize():重设容器大小
  • assign():替换容器的内容

而正如它们定义的那样,resize会把容器的size属性的值修改,而assign会把范围内的元素全部替换,之后再把size属性的值修改。详见下面代码与测试截图:

int main()
{
	vector<int> vec;

	vec.assign({ 1,2,3,4,5,6,7,8,9 });	// 列表初始化 std::initializer_list

	cout << "The current size is :" << vec.size() << "\n"		// 当前的元素个数
		<< "The available space is: " << vec.capacity() << "\n";	// 当前的容量大小
	for (auto const& v : vec) cout << v << " ";						// 当前的元素内容					
	cout << "\n------------------------" << endl;



	vec.assign(5, 1);
	// vec.resize(5, 1);


	cout << "The current size is :" << vec.size() << "\n"		
		<< "The available space is: " << vec.capacity() << "\n";
	for (auto const& v : vec) cout << v << " ";								
	cout << "\n------------------------" << endl;

	/*
	使用vec.assign(5, 1);输出
		The current size is :9
		The available space is: 9
		1 2 3 4 5 6 7 8 9
		------------------------
		The current size is :5
		The available space is: 9
		1 1 1 1 1
		------------------------

	使用vec.resize(5, 1);输出
		The current size is :9
		The available space is: 9
		1 2 3 4 5 6 7 8 9
		------------------------
		The current size is :5
		The available space is: 9
		1 2 3 4 5
		------------------------
*/

	return 0;
}

在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我叫RT

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值