『C++&C语言』Vector shrink 请求容器降低其容量和size匹配 shrink_to_fit();

『C++&C 语言』Vector shrink 请求容器降低其容量和 size 匹配 shrink_to_fit();

一、先从 size 和 capacity 说起

resize(),设置大小(size);
reserve(),设置容量(capacity);

size()是分配容器的内存大小,而 capacity()只是设置容器容量大小,但并没有真正分配内存。 打个比方:买了一个新房子,新房子里可以放 3 张床 reserve(3),这是说房子的容量是最多放 3 张床,但是屋里并不是有三张床,二 resize(3),房里安装了 3 张床,此时房里的床可以使用了。
reserve为容器预留足够的空间,避免不必要的重复分配,分配空间大于等于函数的参数,影响 capacity。但 reserve 的功能确实蹩脚,只能用 reserve 是的 capacity 变得比之前大。
resize调整容器中有效数据区域的尺寸,如果尺寸变小,原来数据多余的截掉。若尺寸变大,不够的数据用该函数第二个参数填充,影响 size。
由于 vector 是顺序容器,在内存中分配了一块连续的存储空间。为了保证动态添加元素的高效率,因此必须预先为 vector 分配一段空间,这个空间就是 capacity。
而容器中元素的个数就是 size(),在容器中,capacity 总是大于等于 size;
当 vector 数组插入数据量过大时,其 capacity,会变得很大,且清空 vector 容器后,还会保留原分配的容量 capacity。系统不会自动收回空间吗?真的不会!!!!!!!!
我们一点一点写程序把 risize()跟 reserve()弄那个明白。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
vector<int> t;
for(int i=0;i<1000;i++)
{
t.push_back(i);
}
cout<<t.size()<<' ';
cout<<t.capacity()<<endl;
t.resize(5);
t.reserve(1);
cout<<t.size()<<' ';
cout<<t.capacity()<<endl;
t.resize(20);
t.reserve(2000);
cout<<t.size()<<' ';
cout<<t.capacity()<<endl;
t.resize(10000);
cout<<t.size()<<' ';
cout<<t.capacity()<<endl;

运行结果
在这里插入图片描述
我们可以看出当 Vector 内只有五个元素时其分配空间还是 1024,而 reserve 却不能做出任何反应,蹩脚,但是 reserve 能让容器空间变大,其实 vector 既然是容器他就会自动分配更多空间,所以 reserve 差评,这不是重点,重点是怎么将 vector 多分配出来的空间收回。有同学要说了 clear()。

1
2
3
4
5
6
7
8
9
10
vector<int> t;
for(int i=0;i<1000;i++)
{
t.push_back(i);
}
cout<<t.size()<<' ';
cout<<t.capacity()<<endl;
t.clear();
cout<<t.size()<<' ';
cout<<t.capacity()<<endl;

运行结果
在这里插入图片描述
然而 clear 只是将容器内的元素清空了,对于分配的 capacity,却没有作用。在这里有几种方法实现降低容量 ,但是其原理相同。

1
2
3
4
5
6
7
8
9
10
11
12
13
vector<int> t;
for(int i=0;i<1000;i++)
{
t.push_back(i);
}
cout<<t.size()<<' ';
cout<<t.capacity()<<endl;
t.clear();
cout<<t.size()<<' ';
cout<<t.capacity()<<endl;
t.shrink_to_fit();
cout<<t.size()<<' ';
cout<<t.capacity()<<endl;

运行结果
在这里插入图片描述
当时我比较苦恼时大佬给我了两个方法,上面那个,还有一个底层的写法如下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
vector<int> t;
for(int i=0;i<1000;i++)
{
t.push_back(i);
}
cout<<t.size()<<' ';
cout<<t.capacity()<<endl;
t.clear();
cout<<t.size()<<' ';
cout<<t.capacity()<<endl;
auto newt=t;
swap(newt,t);
cout<<t.size()<<' ';
cout<<t.capacity()<<endl;
cout<<newt.size()<<' ';
cout<<newt.capacity()<<endl;

在这里插入图片描述
显然 t 容器已经被降低容量,但是其容量降低的代价时 newt 的容量变大。所以这种方法不可取。还有第三种方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
vector<int> t;
for(int i=0;i<1000;i++)
{
t.push_back(i);
}
cout<<t.size()<<' ';
cout<<t.capacity()<<endl;
t.clear();
cout<<t.size()<<' ';
cout<<t.capacity()<<endl;
vector<int>(t).swap(t);
cout<<t.size()<<' ';
cout<<t.capacity()<<endl;

在这里插入图片描述
以上就是对于 vector 的 capacity 的探究,当数据量较少时,多分配的 capacity 可以忽略,但是当数据量很大之后,就不能忽略了,所以当你 clear 之后记着 shrink 呀。


『C++&C语言』Vector shrink 请求容器降低其容量和size匹配 shrink_to_fit();
https://chiamzhang.github.io/2024/06/29/『C++&C语言』Vector shrink 请求容器降低其容量和size匹配 shrink_to_fit();/
Author
Chiam
Posted on
June 29, 2024
Licensed under