以vector為例,我們都知道可以用reserve()和resize()函數來為容器預留空間或者調整它的大小。
不過從它倆的名字上可以看出區別:
reserve():serve是“保留”的詞根,所以是用來保留,預留容量的,並不改變容器的有效元素個數。
resize():size是“大小”的意思,它主要用來調整容易有效元素的個數,有時候也會造成容量變大。
先解釋兩個概念:
容量:即capacity,是指容器在自由內存中獲得了多大的存儲空間,容量為100並不代表容器就有100個元素,可能容量只有10個,剩下的90個都是閑置的未定義內存空間。
大小:即size,指的是容器中實際元素的個數,大小為100就代表容器有100個已經存在的元素。
好了,下面對reserve()和resize()分別做一個介紹:
1. reserve()
它的函數原型是這樣的:
void reserve(size_type n);
對於n值的大小,分兩種情況:
(1)如果n大於容器現有的容量(capacity),比如你容器原來是100的容量,我現在指定n=200,那么就需要在自由內存區為整個容器重新分配一塊新的更大的連續空間【因為vector是順序容器,所以存儲空間是連續的,如果之前的存儲空間不夠了,必須這樣做】,然后將容器內所有的有效元素從舊位置全部復制到新位置,這個過程是調用拷貝構造函數,然后釋放舊位置的所有存儲空間,並調整容器的元素位置指示器。所以reserve的時候如果n比原來的大,結果只是讓容器的冗余容量(即沒有分配元素的存儲區)變大,容器的實際大小,即元素個數並沒有改變。
(2)如果n小於容器原來的容量,那么這個函數什么作用都沒有。相當於白調用了。
2. resize()
它的函數原型是這樣的:
void resize(size_type n, const T& c = T());
其中n是要保留的元素個數,如果是要新增元素的話,c則是新增元素的默認初始值。
對於n值的大小,分三種情況:
(1)如果n大於容器當前的大小(即容器的size,這里和capacity無關),則在容器的末尾插入n-size()個初始值為c的元素;如果沒有指定初始值,那就元素類型的默認構造函數來初始化。
(2)如果n小於容器當前的大小,則刪除末尾的size()-n個元素,這樣就導致容器的大小變了,size 變小了。但是這種類型的容器在刪除一個元素的時候並不會釋放元素本身的內存空間【這也是為了保留這塊空間以避免將來要插入新元素的時候又要進行存儲空間重分配】,所以容器的容量即capacity其實是沒有改變的。
(3)n等於容器當前的大小,則什么也不做。
顯然,reserve和resize的共同點就是:都不縮減容器本身的容量。即對內存空間並沒有影響。那么要是當你覺得容器的容量太多的時候,應該如何縮減容量呢。這時候需要用到一個利用swap函數的技巧。
