我们都知道可以用reserve()和resize()函数来为容器预留空间或者调整空间的大小。那么二者的区别到底在哪里呢?下面 以vector 为例简单讲解下。
首先,从二者的名字上可以看出区别:
reserve(): serve 是“保留”的词根,所以是用来预留容量的,并不会改变容器的有效元素个数。即用reserve()开辟空间时,仅改变capacity大小,与size无关。
resize(): size 是“大小”的意思,它主要用来调整容器有效元素的个数,有时候也会造成容量的改变。因此用resize()开辟空间时,会对增加的空间全部进行初始化,使得有效元素个数增加。
这里我解释两个概念:
容量: 即capacity,是指容器在自由内存中获得存储空间的大小,容量为100时并不代表有100个元素,可能有效元素只有10个,剩下的90个都是闲置的未定义的内存空间。
大小: 即size,指的是容器中实际(有效)元素的个数,当大小为100时,就代表容器中已存在100个元素,容量一定不小于100。
下面对reserve( ) 和resize( ) 函数分别进行介绍:
1. reserve( )
通过查看vector的reserve()文档,了解到它的函数原型如下:
void reserve( size_type n) ;
1)如果n值大于容器现有容量(即capacity),那么就在自由内存空间为整个容器重新分配一块更大的连续空间【因为vector是顺序容器,所以存储空间一定是连续的】,然后将容器内所有的有效元素从旧空间的位置全部复制到新空间相应的位置,这个过程要调用拷贝构造函数(在前面博客 模拟实现vector容器中拷贝构造函数的实现代码),然后释放旧空间,并调整容器的元素位置指示器。所以reserve函数的结果只是让容器的冗余容量变大,容器的实际大小即元素个数并没有变化。
2)如果n值小于容器的现有容量,那么这个函数没有任何作用。
2. resize( )
通过查看vector的resize()文档,了解到它的函数原型如下:
void resize (size_type n, const T& c = T());
这里n是要保留元素的个数,如果要新增元素则c是新增元素默认初始化的值。
1)如果n值大于当前容器的大小(即容器的size,与capacity无关),则在容器的末尾插入n-size()个初始值为c的元素,若如果没有指定初始值,那就用元素类型的默认构造函数来初始化。这里有可能使容器的容量变大。
2)如果n值小于当前容器的大小,则删除末尾的size()-n个元素,这样会导致容器的大小size变小。但是在这种类型的容器在删除元素后并不会释放元素本身的内存空间【这也是为了保留这块空间以避免将来要插入新元素时又要进行重新分配存储空间带来的麻烦】,所以容器的容量capacity并没有改变。
3)n值等于当前容器的大小时,什么也不做。
显然,
reserve和resize的共同点如下:
- 当 填写的n值<=当前值 时,都不会缩减容器本身的容量,即对原内存空间并无影响。
- 当 填写的n值>当前值 时,都会增大容器本身的容量 即capacity会变化。
reserve和resize的区别点如下:
- reserve在不能改变容器容量时,什么都不做;reserve在能改变容器容量时,只会增加capacity即容器冗余量,但容器的size不会变化。
- resize在不能改变容器容量的时候,有可能增加/减少了元素个数即size(此时size<=capacity);resize在可以改变容器容量的时候,增加size的同时一定增加了capacity,且无冗余量,此时再增加size一定还要增加capacity。