STL原始碼剖析學習記錄 一

2022-07-27 09:24:12 字數 3826 閱讀 1729

stl六大元件

1.容器(containers):如vector,list,set,map,從實現角度來看stl容器是一種類模板(class template)。

2.演算法(algorithms):如sort,search,copy,erase... 從實現的角度來講stl演算法是一種函式模板(function template)

3.迭代器(iterators):演算法與容器之間的膠合劑,可以認為是互相使用的工具,所謂的"泛型指標"。

4.仿函式(functors):行為類似函式,可作為演算法的某種策略,從實現的角度,仿函式是一種過載了operator()的class或class template,一般函式指標可視為狹義的仿函式。

5.配接器(adaptor) 

6.配置器(allocators):負責空間配置與管理,從實現的角度來說,配置器是乙個實現了動態空間配置,空間管理,空間釋放的class template。

第二章 allocator

關於一級空間配置器:

直接使用malloc、free、realloc進行記憶體管理操作。且在記憶體不足時,會陷入oom_malloc,即模擬c++的set_new_handler。但沒有new_handler,則丟擲bad_alloc;

關於二級空間配置器:(避免太多小額區塊照成記憶體碎片)

對於大於128bytes的,直接使用malloc和free;

對於小於128bytes的記憶體申請,使用16個空閒鍊錶維護,每個鍊錶相差8bytes。

a. 對於申請的記憶體會up到8的整數倍的大小size,再去據此查詢合適的空閒鍊錶。

b. 如果該空閒鍊錶足夠,則直接分配;

c. 否則,向記憶體池申請20個這樣的size,如果記憶體池足夠,則返回;

d. 否則,記憶體池如果有這樣的size,則盡可能多的返回;

e. 否則,將記憶體池的剩餘的空間賦予對應的空閒鍊錶,並malloc申請40個這樣的size的記憶體;

f. 如果申請成功,則進行正常返回(留20個在記憶體池);

g. 如果申請失敗,則呼叫一級空間配置器(其由oom的機制),分配40個這樣的size的記憶體;

h. 如果一級空間配置器成功,則一切ok;否則,會觸發bad_alloc;

this chapter fowards from 

第三章 迭代器與traits技巧

根據 type_tag 來進行最有效的迭代器操作,比如random access iter 支援 下標操作,bidirectional iterator 支援 ++ -- 操作

traits 程式設計技巧利用c++ 模板偏特化以及c++ template編譯期型別推斷的特性 有效解決templatetemplate 等型別,在本書中讓其直接歸屬於random access 類別

個人的理解在於新增了乙個中間層,並利用c++模板型別推導 使其去執行返回值為模板型別,或者需要在函式中定義的模板型別,另外在處理指標與常量指標的時候,利用模板偏特化來執行特化的版本。從而達到類別推導的效果。此概念已經在effective c++一書中講到過

第四章 序列式容器

採用線性連續空間;(動態空間)

支援random access iterators;(隨機訪問,時間複雜度為o(1))

插入會導致之後的迭代器失效,如果引起擴容,則全部失效;刪除會使得之後的迭代器失效;

採用環狀迴圈鍊錶;(有輔助頭結點)

插入/接合不會使得迭代器失效;刪除只會使得當前迭代器失效;

採用分段連續線性空間;

允許在常數時間內對頭端/尾端進行插入或刪除;(當然中間的位置也可以操作,但複雜度高,設計資料的移動)

提供了random access iterator,但是其內部實現複雜;

實現描述:

deque內部會維護乙個map陣列(存放指標指向乙個連續的線性空間);

在中間刪除erase元素時,會使得前面/後面的資料移動(選擇需要移動資料少的方面進行移動);對於插入insert類似;

當map空間不夠時,會存在map重分配策略:1)map沒有佔滿一般時,會將map陣列中的資料移動在中間,以使得前後空閒(比如一直在push_front,會出現這種情況);2)否則,進行重新分配乙個兩倍大的map陣列,並將原來的指向連續線性空間的指標拷貝進來,並交換兩個map,釋放舊map;

注:在動map陣列時,由於首尾迭代器會指向map對應位置,因此也需要調整首尾迭代器;

對於遞增/遞減迭代器,跨不同的連續線性空間時,會根據當前的map上的位置,查詢到下乙個map位置,再移動;

deque的資料儲存空間是以連續線性空間為單位的;(多餘時釋放)

注:連續線性空間也被稱為緩衝區;

4)stack(介面卡,預設使用deque實現)

5)queue(介面卡,預設使用deque實現)

6)heap(預設大頂堆)

實現一顆完全二叉樹,且父節點大於子節點,並將其放置於vector陣列中;(不提供遍歷功能和迭代器)

對於插入節點,將其放置於最後的位置,然後進行percolate up上溯:將新節點與父節點比較,如果其值更大,則交換,直至不滿足條件或者已達父節點;

對於刪除最大節點(即堆頂節點),將其與最後乙個元素的位置交換,然後進行percolate down下溯:將該節點和其較大的子節點對換,並持續下放,直至葉子節點;然後再對該葉子節點進行上溯(不能在中間直接停掉嗎??)

對於make_heap產生乙個堆:從下往上構建堆。

注:將一顆完全二叉樹存放在陣列中,第乙個元素不存放資料,之後將該顆完全二叉樹層次遍歷放入陣列中,那麼存在性質:在i處的節點,其左節點必然位於2*i,其右節點必然位於2*i+1;

7)priority_queue

採用heap實現,預設為大頂堆(less);

不提供遍歷和迭代器;

8)slist

單向鍊錶;(有輔助頭結點)

對於插入、刪除、結合等不會使得迭代器失效;但是其中間刪除/插入元素的時間複雜度為o(n),因為其需要遍歷以獲取當前的前乙個節點;因此最好在頭部進行刪除/插入元素操作;

只提供push_front,而不提供push_back;

this chapter fowards from 

STL原始碼剖析(一)

新開了個坑,侯捷的stl原始碼剖析。其實最開始想看原始碼是因為用string用的不熟悉,不知道裡面有哪些函式,也不知道用了函式裡面儲存層會變成什麼樣。比如對string用 會發生什麼,重新分配記憶體還是用指標指向新開的記憶體,strlen的複雜度到底是不是o n 等等,然後就買了侯捷的這本書,結果到...

STL原始碼剖析學習筆記(一)

本系列文章參考 stl原始碼剖析 以自己的觀點解釋stl,當作自己的學習筆記,如有錯誤請指出,謝謝大家。本系列文章適用於對stl有了解但是還未參透者,先從使用的角度,逐漸滲透到其原理,流程為先介紹各種元件及其聯絡,然後介紹容器 vector,list.的使用,並剖析其主要實現原理,然後介紹迭代器,空...

STL原始碼剖析(一)STL簡介

最近看了一點 stl原始碼剖析 這本書,覺得寫得很不錯,寫個部落格記錄下。本篇主要介紹stl的歷史 意義。stl是c 的乙個標準程式庫,其具有劃時代的意義。因為stl包含了先進的技術和程式設計思想。stl價值在於 製造臨時物件的方法是,在型別之後加小括號,並可指定初始值,如shape 3,5 等。相...