OK, 话说序列式容器, 两个问题:

 

Q1. 当前容器有多少个元素?

Q2. 怎样重设容器的元素个数?

 

A1: You know, 所有的STL容器都提供了size()这个操作函数,返回当前容器的元素个数. (参考 C++标准程序库自修教程与参考手册 P146).

A2: vector, deque和list都提供了resize()这个函数来重设元素个数. 对于新增加的元素怎么初始化,resize通过第2个参数说明.

 

好了, size()和resize()清楚后,再来看看 reserve()和capacity(), 他是vector特有的,也是由vector的特性所决定的.

 

 

我们都知道, vector是在内存中是连续分布的,所以设计上总会在所有已经有元素外预留一些空间,否则每次追加新元素时都要再次分配内存,那准备就绪将很低.

假如当vector中可能会存在约500个元素时, 比较两种做法:

1. vector<int> myVec, 然后500次调用 myVec.push_back(****)

2. vector<int> myVec(500), 然后500次调用 myVec.push_back(****)

 

做法2只需要进行1到2次内存分配,而做法1不知道要进行多少次内存分配了.

 

现在, 同样,两个问题:

Q1. 当前容器预留了多大空间(在不进行重新分配内存的前提下,最多可以容纳多少个元素)?

Q2. 怎样重设当前容器的预留大小?

 

A1: capacity().

A2: reserve(). 

 

辨析:

所以说resize()和reserve根本是两回事,resize影响元素的个数. reserve只分配预留的空间.

所以 capacity() >= size() 恒成立.

 

另外有几个问题:

1. vector<int> a(10);  a.reserve(20); a[10] = 999; // 错误, 因为a还没有下标为10这个元素,现在size() ==10, capacity() ==20; 要追加下标10这个元素只能push_back;

 

2. 假设vector<int> sample;

当前size()为50, capacity()为100,经过以下操作:

(1) resize(10).  //size() == 10; 10到49下标的元素被删除. capacity()==100,不变,没有进行内存重新分配.

(2) resize(60).  //size() == 60; 50到59下标用默认构造函数填充. capacity() == 100,不变,没有进行内存重新分配.

(3) resize(60, 9999).  //size() == 60; 50到59下标用9999填充. capacity() == 100,不变,没有进行内存重新分配.

(4) resize(200). //size() == 200; 50到199下载用默认构造函数填充. capacity() == 200, 自动扩容,重新分配内存.

 

(5) reserve(10). //size() == 50; 不变,没有元素被删除, capacity() == 100, 不变. 即reserve调用没起作用.

(6) reserve(60). //size() == 50; 元素没有变, capacity() == 100, 不变. 即reserve调用没起作用.

(7) reserve(200). //size() == 50; 元素没有变, capacity() == 200, 扩容,重新分配内存.

 

3. vector<int> sample(10);  //size() == 10; reserve() == 10;

sample.push_back(999); //size() == 11; reserve () == 15; //自动扩容, reseve为什么不是11呢? 这个超余量是不一定的,也不一定是15.

 

 

 

 

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐