STL相關知識整理 一 allocator

2021-10-08 17:36:20 字數 1717 閱讀 3865

一般而言,我們習慣的 c++ 記憶體配置操作和釋放操作是這樣的:

class foo{};

foo *pf = new foo;

delete pf;

我們看其中第二行和第三行,雖然都是只有一句,當是都完成了兩個動作。但你 new 乙個物件的時候兩個動作是:先呼叫::operator new 分配乙個物件大小的記憶體,然後在這個記憶體上呼叫foo::foo()構造物件。同樣,當你 delete 乙個物件的時候兩個動作是:先呼叫foo::~foo() 析構掉物件,再呼叫::operator delete將物件所處的記憶體釋放。為了精密分工,stl 將allocator決定將這兩個階段分開。分別用 4 個函式來實現:1.記憶體的配置:alloc::allocate();2.物件的構造:::construct();3.物件的析構:::destroy();

4.記憶體的釋放:alloc::deallocate();

template inline void construct(t1* p, const t2& value)
其中construct使用了placement new在sgi版本的stl中,空間的配置釋放都由< stl_alloc.h > 負責。它的設計思想如下:

考慮到小型區塊可能造成記憶體破碎問題(即形成記憶體碎片),sgi stl 設計了雙層級配置器。第一層配置器直接使用malloc() 和 free().第二層配置器則視情況採用不同的策略:但配置區塊超過 128 bytes時,呼叫第一級配置器。當配置區塊小於 128 bytes時,採用複雜的 memory pool 方式。

如上圖所示,自由鍊錶是乙個指標陣列,有點類似與hash桶,它的陣列大小為16,每個陣列元素代表所掛的區塊大小,比如free _ list[0]代表下面掛的是8bytes的區塊,free _ list[1]代表下面掛的是16bytes的區塊…….依次類推,直到free _ list[15]代表下面掛的是128bytes的區塊

同時我們還有乙個被稱為記憶體池地方,以start _ free和 end _ free記錄其大小,用於儲存未被掛在自由鍊錶的區塊,它和自由鍊錶構成了夥伴系統。

如果使用者需要是一塊n位元組的區塊,且n <= 128(呼叫第二級配置器),此時refill填充是這樣的:(需要注意的是:系統會自動將n位元組擴充套件到8的倍數也就是roundup(n),再將roundup(n)傳給refill)使用者需要n塊,且自由鍊錶中沒有,因此系統會向記憶體池申請nobjs * n大小的記憶體塊,預設nobjs=20

參考資料:

STL相關知識

c 的標準模板庫 standard template library,簡稱stl 是乙個容器和演算法的類庫。容器往往包含同一型別的資料。stl中比較常用的容器是vector,set和map等。vectore 乙個vector類似於乙個動態的一維陣列,vector中可以存在重複的元素!1 宣告 1 v...

XMPP 相關知識整理

xmpp the extensible messaging and presence protocol 中文全稱 可擴充套件通訊和表示協議 簡介 可擴充套件通訊和表示協議 xmpp 可用於服務類實時通訊 表示和需求響應服務中的xml資料元流式傳輸。xmpp以jabber協議為基礎,而jabber是即...

patch,diff相關知識整理

diff 命令列選項 原始檔案 新檔案 幾個常用的選項說明 diff的內容預設輸出到stdout上,所以需要把它重定向到乙個檔案中才能儲存,如下 diff un test0 test1 test1.patch如果是資料夾就加個r 常用 rnu就行 patch 命令列選項 待打補丁的檔案或文件 補丁檔...