看了一下vector的實現,感覺C++的內存管理,確實是需要非常認真對待的。
爲了追求效率,自身就需要仔細萬分,總結了3,4點感覺尤其如此。
1.vector的底層實現
這個倒是很簡單,vector就是一段動態分配內存的數組,加上冗餘空間,所以用三個指針(迭代器)就能表示出來,底層的數據結構。
分別是迭代器:start、finish、end_of_storage
其中,finish-start=size,end_of_storage-start=capacity
2.vector的一系列操作
(1)增
push_back<---------->emplace_back
insert<------------------>emplace
emplace是通過填入參數,然後調用其他構造函數,構造對象
push和insert是調用拷貝構造函數構造對象
(2)刪
pop_back
erase
clear
注意:只有對中間操作的函數纔有返回值,且返回值爲iterator。
比如,insert、emplace、erase
最最複雜的操作應該就是insert操作了。
3.copy和copy_backward
copy(first, end, result)
將從first到end的對象拷貝到,result開始的一段內存區域。
順序爲:first--》result, first+1--》result+1,。。。, first+(end-first-1)--》result+(end-first-1)
copy_backward(first, end, result)
順序爲:end-1--》result-1, end-2--》result-2, 。。。, first--》resutl-(end-first+1)
注意:由於不管是copy還是copy_backward都是一個一個移動的,所以當用copy向右移動,且移動長度小於要移動的序列長度時,有坑,會覆蓋。
當copy_backward向左移動,且移動長度,小於要移動的序列長度時,有坑,會覆蓋。
4.copy和uninitialized_copy
這個問題我發現了,後來到知乎上去看,別人也有同樣的疑問:https://www.zhihu.com/question/29993514/answer/53952150
簡單來說,就是copy和uninitialized_copy的區別。
前者假設對象已經構造好了,後者假設是在一段申請的raw memory裏面,要先construct再進行copy。
當然對於原始類型來說,不用construct,所以其實uninitialized_copy如果遇到原始類型會調用copy,如果不是就要一個一個調用construct
這麼做的原因,在上面那個連接裏面有解釋。
簡單來說,就是如果是定義的類,有可能會有動態分配內存持有指針的情況,如果沒有調用構造函數,而是直接使用,
如果直接使用,那麼指針未經初始化,delete一個未經初始化的指針,後果很嚴重。
因爲未經初始化的指針,指向一個不確定的內存空間,這個內存空間可能正在被使用,存放重要信息,
這個時候你把這個內存裏面的內容delete=destroy(調用析構函數)+deallocate(將內存返還給系統)
只能說,雪崩。