C 序列式容器之vector

2022-01-21 21:41:30 字數 2718 閱讀 2279

容器,顧名思義,是用來容放東西的場所。c++容器容放某種資料結構,以利於對資料的搜尋或排序或其他特殊目的。眾所周知,常用的資料結構不外乎:陣列array,  鍊錶list,  樹tree,  棧stack,  佇列queue,  雜湊表hashtable,  集合set、對映表map等等。容器便是容納這些資料結構的。這些資料結構分為序列式與關聯式兩種,故容器也分為序列式容器和關聯式容器。

(圖來自《stl原始碼剖析》)

1.  vector是stl提供的一種序列式容器

所謂序列式容器,其中的元素都序,但未必有序,即元素集合呈線性關係排列,但未必是有序的。c++本身帶了一種序列式容器array,stl再提供其他的序列式容器:vector,list,deque,stack,queue,priority-queue等。

2.   vector底層為動態陣列

vector的資料安排以及操作方式與c++的array十分相似,它們間的唯一差別在於對空間的運用靈活性上。array為靜態陣列,有著靜態陣列最大的缺點:每次只能分配一定大小的儲存空間,當有新元素插入時,要經歷  「找到更大的記憶體空間」->「把資料複製到新空間」 ->「銷毀舊空間」 三部曲, 且對於array而言,這種空間任務壓在使用它的使用者身上,使用者必須把握好資料的數量,盡量在第一次分配時就給資料分配合理的空間(這有時很難做到),以防止「三部曲」帶來的代價,而資料溢位也是靜態陣列使用者需要注意的問題。

而vector使用者不需要親自處理空間運用問題。vector是動態空間,隨著新元素的插入,舊儲存空間不夠用時,vector內部機制會自行擴充空間以容納新元素,當然,這種空間擴充大部分情況下(幾乎是)也逃脫不了「三部曲」,只是不需要使用者自己處理,而且vector處理得更加安全高效。vector的實現技術關鍵就在於對其大小的控制以及重新配置時資料移動效率。

3.  vector的迭代器

對於c語言的陣列,我們使用普通指標就可以對陣列進行各種操作。vector維護的是乙個連續線性空間,與陣列array一樣,所以無論其元素型別為何,普通指標都可以作為vector的迭代器而滿足所有必要的條件。vector所需要的迭代器操作,包括operator*,operator->,operator++,operator--,operator+=,operator-=等,普通指標都具有。

故,普通指標即可滿足vector對迭代器的需求。所以,vector提供了random access iterators。

4. vector的資料結構

正如上面所說,vector底層為連續線性空間。它使用兩個迭代器:begin與finish該連續線性空間中的第乙個元素的位置與超出末端的第一位位置,這兩個迭代器標誌了連續線性空間的已使用範圍,並以end_of_storage迭代器標準整個連續線性空間的尾端。這裡begin與finish符合stl「前開後閉」的標準。

基於這三個迭代器,可以完成許多操作。包括提供首尾標示、大小、容量、空容器判斷、運算子、最前端元素值、最後端元素值等等。

值得注意的是,容器的大小與容量是不一樣的概念。只有在容器滿載時,大小才等於容器。在上面這張圖中,大小size為已使用的儲存空間長度,而容量為已使用+未使用的儲存空間長度。從它們的實現**上也可以看出來:

size_type size() const

size_type capacity ()

const

5. vector的記憶體分配策略標準庫的實現者使用了這樣的記憶體分配策略:以最小的代價連續儲存元素。為了使vector容器實現快速的記憶體分配,其實際分配的容量要比當前所需的空間多一些,vector容器預留了這些額外的儲存區用於存放新增的新元素,於是不必為每個新元素進行一次記憶體分配。當繼續向容器中加入元素導致備用空間被用光(超過了容量 capacity),此時再加入元素時vector的記憶體管理機制便會擴充容量至兩倍,如果兩倍容量仍不足,就擴張至足夠大的容量。容量擴張必須經歷「重新配置、元素移動、釋放原空間」這個浩大的工程。按照《stl原始碼剖析》中提供的vector原始碼,vector的記憶體配置原則為:

如果vector原大小為0,則配置1,也即乙個元素的大小。

如果原大小不為0,則配置原大小的兩倍。

當然,vector的每種實現都可以自由地選擇自己的記憶體分配策略,分配多少記憶體取決於其實現方式,不同的庫採用不同的分配策略。

需要注意的是,使用vector迭代器時要時刻注意vector是否發生了擴容,一旦擴容引起了空間重新配置,指向原vector的所有迭代器都將失效。 

關於vector各種介面的使用方法這裡就不再贅述了。對於vector有新認識會及時更新博文。

STL序列式容器之vector

序列式容器 序列式容器 可序列集群,其中的元素都可序,但未必有序。vector概述 vector的資料安排以及操作方式,與array非常相似。兩者的唯一差別在於空間的運用的靈話性,array 是靜態空間,一旦配置了就不能改變 要換個大 或小 一點的房子,可以,一切瑣細得由客戶端自己來 首先配置一塊新...

c 序列式容器(一) Vector

vector維護的是乙個連續的線性空間,有三個比較重要的指標,start指向目前使用空間的頭,finish指向目前使用空間的尾,end of storage指向目前可用空間的尾。增加新元素的時候,如果備用空間不夠,會將容量擴容到兩倍。會經歷 重新配置,元素移動,釋放原空間 等過程,因此,擴容的時候效...

實現序列式容器 vector

概述 在stl諸多容器中vector一定是使用率最高的了,它使用和資料結果上與array相類似,兩者唯一差別在於 array是靜態空間,而vector是可變空間。因此通常將vector看作可變陣列。由於vector方法較多,在主要此討論實現vector中要注意的幾個點 對於vector而言維護的是一...