1. 程式人生 > >C++學習筆記(十五):vector物件在記憶體空間中是如何增長的

C++學習筆記(十五):vector物件在記憶體空間中是如何增長的

vector物件在記憶體空間中是如何增長的

我們都知道vector物件是動態儲存的,從這一點看有點像連結串列,可以動態的增加或減少元素。我們也知道連結串列中是有指標變數,專門用於儲存上一個和下一個元素的地址。正是因為這兩個指標的存在,我們才能做到動態的儲存資料,即不用像陣列那樣必須事先申請好空間。連結串列的缺點就是不能夠快速的隨機訪問其中元素,必須通過指標層層查詢。

但是,vector既可以實現動態儲存資料,而且支援快速隨機訪問(用下標或者指標訪問元素)。對於能夠用下標查詢的資料型別,其儲存方式必定是連續的,即每個元素緊挨著前一個元素儲存。

這樣對於vector來說,就會出現一個問題,我在初始定義vector的時候該給其申請多少記憶體空間?如果申請的很小,那麼我來了新的資料改存放在哪裡?如果申請的很大,我用不完,那豈不是很浪費記憶體空間?

當然對於vector這種標準庫型別,通常我們只關心如何使用它,而不關心其實如何實現的。不過對於其在儲存空間的實現方式還是瞭解一下比較好。

我們知道容器中元素連續儲存,且容器大小是可變的,考慮向vector中新增元素會發生什麼?如果沒有空間容納新的元素,容器不可能簡單的將其新增到記憶體的其他位置,因為vector的元素必須連續儲存。因此容器必須分配新的空間來儲存已用的元素和新的元素。將已有元素從舊位置移動到新空間,然後新增新元素,釋放舊空間。如果說我們每新增一個新的元素就執行一次這樣的操作,顯然效能會慢到我們不可接受。

為了避免上面的代價,標準庫採用了可以減少容器空間重新分配的策略。當不得不獲取新的記憶體空間時,vector的實現通常會分配比新的空間需求更大的記憶體空間。容器預留這些空間作為備用,從而用來儲存更多新的元素。這樣,就不需要每次新增新的元素都重新分配容器的記憶體空間了。

vector型別提供了一些成員函式,允許我們與它的現實中記憶體分配部分互動。

c.capacity()     不重新分配記憶體空間的話,c可以儲存多少元素

c.reserve(n)     分配至少能容納n個元素的記憶體空間

c.shrink_to_fit()  將capacity()減少為size()相同大小。size()為vector已經儲存元素個數。