C++ Primer 第九章 9.4 Vector对象是如何增长的 练习和总结

9.4 Vector对象是如何增长的

vector对象为了支持快速随机访问,其物理存储方式是连续存储的,又因为vector是动态大小的,所以这就涉及到了一个问题。

如果当前的vector容器分配的存储空间空间已经满了,不能再添加新的元素,那么就需要重新分配一块内存空间,将原来的值复制过去并添加新的元素。

但是如果每次添加都重新分配内存空间的话,vector的效率会非常的低。

所以为了避免这种低效的方式,vector有自己的内存增长方式,需要注意的是,这种增长方式不同的标准库实现者策略是不同的。

总的来说,vector和string通常会分配比新空间需求(新空间需求即:容器当前需要存进去多少元素)更大的内存空间。

和容量相关的成员函数如下:
在这里插入图片描述
1.之前说了容器实际能够容纳的元素个数通常大于或者等于当前的需求,也就是容器会有多余的空间,使用shrink_to_fit()可以收回多余的空间,但是这依赖于标准库的实现者,实现者有权不收回多余的空间。
2.capacity,表示容器在不重新分配内存空间的情况下,最多可以容纳多少元素。
3.reserve,改变容器的capacity。需要注意的是,reserve(n)分配的内存空间是小于等于capacity的。且当n小于容器当前实际存储的元素个数时,reserve是不会其作用的。也就是说reserve的n只是一个参考,当n<size()时,reserve不会起作用,当n>size()时,capacity()>=n

capacity()和size()的区别

前者表示在不重新分配内存空间的情况下,最多可以容纳多少元素。
后者表示当前容纳了多少元素。

resize()和reserve()的区别

resize()改变的是size()的大小,但是如果resize(n),n大于capacity(),就会改变capacity(),reserve()改变的是capacity()的大小,reserve(n),n<=capacity()

只有在insert(push_back也算insert),seize==capacity(),或者resize(n),reverse(n)中的n大于capacity()时,vector才会重新分配内存空间

练习

9.35
capacity表示vec在不重新分配内存空间的情况下,最多可以容纳多少元素

size()表示vec当前以及容纳多少元素

9.36
capacity()永远>=size()

9.37
这个list,array的存储接口有关,list在内存上并不是连续存储的,所以插入新元素时,可以直接分配新的内存空间。array的内存是固定的,所以没法开辟新的存储空间,size()就是它的最大容量。

9.38

VS2017的标准库

vector<int> vec;
	cout << "size:" << vec.size() << "capacity:" << vec.capacity() << endl;

	vec.push_back(1);
	cout << "size:" << vec.size() << "capacity:" << vec.capacity() << endl;
	for (int i = 0; i < 10;i++) {
		vec.push_back(i);
		cout << "size:" << vec.size() << "capacity:" << vec.capacity() << endl;
	}
	vec.reserve(20);
	cout << "size:" << vec.size() << "capacity:" << vec.capacity() << endl;
	for (int i = 0; i < 50; i++) {
		vec.push_back(i);
		cout << "size:" << vec.size() << "capacity:" << vec.capacity() << endl;
	}

程序的输出:

size:0capacity:0
size:1capacity:1
size:2capacity:2
size:3capacity:3
size:4capacity:4
size:5capacity:6
size:6capacity:6
size:7capacity:9
size:8capacity:9
size:9capacity:9
size:10capacity:13
size:11capacity:13
size:11capacity:20
size:12capacity:20
size:13capacity:20
size:14capacity:20
size:15capacity:20
size:16capacity:20
size:17capacity:20
size:18capacity:20
size:19capacity:20
size:20capacity:20
size:21capacity:30
size:22capacity:30
size:23capacity:30
size:24capacity:30
size:25capacity:30
size:26capacity:30
size:27capacity:30
size:28capacity:30
size:29capacity:30
size:30capacity:30
size:31capacity:45
size:32capacity:45
size:33capacity:45
size:34capacity:45
size:35capacity:45
size:36capacity:45
size:37capacity:45
size:38capacity:45
size:39capacity:45
size:40capacity:45
size:41capacity:45
size:42capacity:45
size:43capacity:45
size:44capacity:45
size:45capacity:45
size:46capacity:67
size:47capacity:67
size:48capacity:67
size:49capacity:67
size:50capacity:67
size:51capacity:67
size:52capacity:67
size:53capacity:67
size:54capacity:67
size:55capacity:67
size:56capacity:67
size:57capacity:67
size:58capacity:67
size:59capacity:67
size:60capacity:67
size:61capacity:67

可以看到当size()小于10时,容器的size()和capacity()是一样的,大于10之后,capacity()>=size(),且越往后分配,当capacity()==size()时,重新分配的内存空间要比之前重新分配的内存空间的增量要大。

9.39
向svec中添加元素,添加完成之后,将vec的大小为resize()原来的1.5倍。

9.40
因为reserve(n),capacity可能大于等于n,所以实际的结果我们是不确定的,需要根据具体的编译器来确定。

假定reserve(n)之后,capacity等于n,那么
读入256个词,capacity为1024
读入512个词,capacity为2014,
后面的就看具体的标准库如何实现的了
在VS2017下
1000,capacity为1536
1048,capacity为2304

使用的代码如下

vector<string> vec;
	vec.reserve(1024);
	cout << "size:" << vec.size() << "capacity:" << vec.capacity() << endl;

	int count = 1048;
	for (int i = 0; i < count;++i) {
		vec.push_back("233");
	}
	vec.resize(vec.size()+vec.size()/2);
	cout << "size:" << vec.size() << "capacity:" << vec.capacity() << endl;

发布了54 篇原创文章 · 获赞 6 · 访问量 3327

猜你喜欢

转载自blog.csdn.net/zengqi12138/article/details/104246635