C 入門之vector的底層實現詳解

2022-09-29 12:12:13 字數 2939 閱讀 2061

目錄

上一小節,我們講解了vector的使用,也大概了解了其建立物件,增刪改查資料等操作.那麼今天,我們就來大致實現一下吧.

在標準c++中,vector同樣是乙個模板,並且其底層實現用的是三個指標,然後利用這三個指標相互加減,達到儲存效果.

而vector和string類似,本質是都是乙個順序表.

template

class vector

private:

t* _start; //順序表的頭

t* _finish; //順序表有效長度位置

t* _end_of_storage; //順序表末尾

};上一章節已經講解,建構函式比較多,這裡只是為了簡單實現,所以博主就實現乙個最簡單的建構函式,即無參構造.

vector():_start(nullptr),_finish(nullptr),_end_of_storage(nullptr) {}

想要獲取size,該怎麼實現呢?我們在定義初始結構的時候,已經知道其底層是利用的三個指標,所以size等於_finish - _start.

size_t size() const //加const是保證const物件也可以用

同樣的道理,capacity就應是_end_of_storage - _start;

size_t capacity() //加const是保證const物件也可以用

我們在後面會實現乙個介面,叫做push_back(),它的作用是把資料放進vector,但如果空間不足了呢?這就需要我們的增容函式reserve了.

其引數是無符號整型n,代表要開n個空間

void reserve(size_t n)

_start = tmp; //移交空間

_finish = _start + sz; //更新_finish

_end_of_storage = _start + n; //更新_end_of_storage}}

這個想必大家現在已經比較習慣了吧?他有兩個引數,會分情況討論是否大於size()而進行引數賦值.

void resize(size_t n,const t& val = t())

iterator end() //普通介面

const_iterator begin() const

const_iterator end() const //const介面

該介面的實現操作一般是先檢查容量是否充足,然後把資料放進去,最後size大小加一.

void push_back(const t& val)

*_finish = val;

_finish++;

}實現該介面的操作一般是先檢查是否還存在資料,然後size大小減一

void pop_back()

同樣的道理,一般先檢查容量是否充足,如果不夠,需要警惕迭代器失效問題,然後移動該位置及以後的所有資料,最後插入資料.

官方文件定義其返回值為新插入資料的位置

iterator insert(iterator pos,const t& val)

iterator cur = end();

while(cur > pos)

*pos = val;

_finish++;

return pos;

}該介面的操作一般是從pos後位置開始,所有資料前挪一單位.但是在挪之前,需要檢查是否還存在資料

官方文件定義其返回值為刪除資料的下一位置

iterator erase(iterator pos)

--_finish;

return pos;

}vector(const vector& v):_start(nullptr), _finish(nullptr), _end_of_storage(nullp程式設計客棧tr)

}上面我們實現了迭代器,但是vector還支援索引取值,博主這裡便實現兩個過載吧

t& operator(size_t i)

const t& operator(size_t i) const

vector& operator=(vector v) //注意哦~,我這裡故意寫的傳值引數,而不是引用,是為了下面進行交換

在實現了上面的一系列操作以後,有沒有覺得我們已經大功告成了?其實這裡還隱藏著乙個小小bug!.為什麼呢?看下面'

int main()

初一看,好像並沒有什麼錯誤哎?但是一執行就會發現,當插入第5個元素的時候,就報錯了.這是什麼原因呢?

除錯發現,問題出在了reserve上面,因為push_back之前,會檢查容量,那麼我們現在重新瞅瞅 reserve存在什麼問題呢?

void reserve(size_t n)

_start = tmp; //移交空間

_finish = _start + sz; //更新_finish

_end_of_storage = _start + n; //更新_end_of_storage}}

大家有發現什麼問題了嗎?

沒錯,問題出現在memcpy上面,當容量不足,reserve就會增加容量,然後把原來空間的內容值拷貝到新空間.

但是原來空間的內容也就只有三個指標呀,拷貝過去後,新空間和源空間都指向了同一塊空間,而我們又會釋放原空間.

所以,當繼續尾插第5個元素時候,就報錯了,因為空間已經不存在了!!!,被釋放了.

那怎麼解決呢?這裡便只能用迴圈,把string值賦給新空間了.

void reserve(size_t n)

delete _start;

}_start = tmp;

_finish = _start + sz;

_endofstorage = _start + n;

}本文標題: c++入門之vector的底層實現詳解

本文位址:

C語言資料結構之vector底層實現機制解析

目錄 通過分析 vector 容器的源 不難發現,它就是使用 3 個迭代器 可以理解成指標 來表示的 其中statrt指向vector 容器物件的起始位元組位置 finish指向當前最後乙個元素的末尾位元組 end of指向整個 vector 容器所占用記憶體空間的末尾位元組。如圖 演示了以上這 3...

c 之vector容器入門

對於c 的vector容器的函式應用 include include include using namespace std intmain cout cout 迭代器形式結果 for it vt.begin it vt.end it cout cout vt元素個數是 size函式 插入元素函式 ...

STL中vector的底層解析及簡易實現

vector是一種動態增長的陣列,當原始容量被用盡後,在別的地方進行擴充,大小為原來的2倍,然後將內容拷貝過去 成長過程如下圖所示 下面是vector的關鍵源 templateclass vector iterator end size type size const size type capac...