STL原始碼剖析 第二章 空間配置器

2022-07-09 18:36:10 字數 1470 閱讀 9222

c++記憶體配置操作和釋放操作如下:

1

class

foo;

2 foo* pf=new foo; //

配置記憶體,然後構造物件

3delete pf; //

將物件析構,然後釋放記憶體

記憶體配置操作由 alloc:allocate() 負責,記憶體釋放操作由 alloc:deallocate() 負責;物件構造操作由 ::construct() 負責,物件析構操作由 ::destroy() 負責。

destroy() 有兩個版本,第乙個版本接受乙個指標,析構指標所指的物件。

第二個版本接受 first 和 last 兩個迭代器,將 [first,last) 範圍內所有物件析構。在這裡我們就要考慮這些物件是否值得我們一次次的呼叫實際沒有作用的析構函式,所以我們就利用 value_type() 求出迭代器指向物件的型別,並呼叫相應的 __type_traits<> 判斷物件的析構函式是否是trivial的。

記憶體配置和釋放操作複雜很多。分別第一級配置器和第二級配置器。第一級配置器的 allocate() 和 realloc() 都是在呼叫 malloc() 和 realloc() 不成功後,改呼叫 oom_malloc() 和 oom_realloc() 。後兩者都有內迴圈,不斷呼叫需要客端設計的「記憶體不足處理例程」,如果沒有設計,就丟出 bad_alloc 異常資訊。

第二級配置器

union obj;

這個地方 client_data 的位址等於 obj 的位址,那麼為什麼我們要加上這個可有可無的**呢?可能是用 obj->client_data 可以避免 (char*)  的強制轉換吧,雖然這種方式也沒有出現,說白了這行**就沒有用......

用到了乙個鍊錶陣列 free_list[16] ,其中存放的區塊大小分別是8、16、24... 

配置過程如下:

1.大於128byte 由第一級配置器來

2.小於則尋找 free_list 中最合適的一種

3.進入索引後發現這種裡面有,直接抽出一塊

4.發現裡面沒有,填充 free_list

5.從記憶體池中抽取20*size 大小的記憶體,如果有,size拿出來,19*size 給free_list

6.沒有,20*size,size大小有的話就將就一下

7.size都沒有的話,把記憶體池中剩下的歸到 free_list 中,因為記憶體池中剩餘大小一定是8的倍數,所以一定有合適的 free_lists 可以匹配。完事以後 malloc 2*size+n(附加量),malloc 不成的話就去 free_list 裡找高階的索引,找到就歸入記憶體池並呼叫一次自己,因為此時記憶體池中有東西了,可以重複5-7的步驟了。高階的索引裡面都沒有東西的話就完蛋了,只能寄希望於第一級配置中 out-of-memory 方法,因為第一級的正常辦法也是 malloc ,這條路已經行不通了。如果 out-of-memory 成了的話就歸入記憶體池,再呼叫一次自己。

STL深入剖析 第二章 空間配置器

本章主要是空間配置器,一般我們都不用管的。不過弄懂這個對接下來的很多內容都可以搞懂,這個還可以提高stl的效率。下面是allocator的必要介面 allocator value type allocator pointer allocator const pointer allocator ref...

STL原始碼第二章 allocator

ifndef pch h define pch h include include include for ptrdiff t,size t include for exit include for uint max include namespace jj return tmp template ...

《STL原始碼剖析》 空間配置器(二)

一。構造和析構基本工具 construct 和 destroy ifndef sgi stl internal construct h define sgi stl internal construct h 欲使用 placement new,需先包含此檔案 include stl begin na...