std::vector的reserve和resize的區別
1. reserve: 分配空間,更改capacity但不改變size
2. resize: 分配空間,更改capacity也改變size
如果知道vector的大小,resize一下可以當數組來用,不會分配多余的內存。
reserve是容器預留空間,但並不真正創建元素對象,在創建對象之前,不能引用容器內的元素,因此當加入新的元素時,需要用push_back()/insert()函數。
resize是改變容器的大小,並且創建對象,因此,調用這個函數之后,就可以引用容器內的對象了,因此當加入新的元素時,用operator[]操作符,或者用迭代器來引用元素對象。
再者,兩個函數的形式是有區別的,reserve函數之后一個參數,即需要預留的容器的空間;resize函數可以有兩個參數,第一個參數是容器新的大小,第二個參數是要加入容器中的新元素,如果這個參數被省略,那么就調用元素對象的默認構造函數。下面是這兩個函數使用例子:
- vector<int> myVec;
- myVec.reserve( 100 ); // 新元素還沒有構造,
- // 此時不能用[]訪問元素
- for (int i = 0; i < 100; i++ )
- ...{
- myVec.push_back( i ); //新元素這時才構造
- }
- myVec.resize( 102 ); // 用元素的默認構造函數構造了兩個新的元素
- myVec[100] = 1; //直接操作新元素
- myVec[101] = 2;
我們都知道, 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.