由於物件的建立分為分配記憶體和呼叫建構函式兩部分,stl allocator使用alloc::allocate()
來分配記憶體,::construct()
構造物件。
construct()
函式只有乙個泛化的版本,destroy()
函式有乙個泛化的針對迭代器的版本,__destroy_aux()
根據是否需要呼叫析構函式進行了特化。
//構造物件
template
inline
void
construct
(t1* p,
const t2& value)
//接受乙個指標呼叫其析構函式
template
inline
void
destroy
(t* pointer)
//把半開半閉區間[first, last)內的所有元素析構掉
//如果該元素的析構函式是trivial的,則什麼也不做 trivial表示可以不呼叫析構函式
//如果該元素的析構函式是non-trivial的,則依序呼叫其析構函式
template
inline
void
destroy
(forwarditerator first, forwarditerator last)
template
inline
void
__destroy
(forwarditerator first, forwarditerator last, t*
)//該元素的析構函式是trivial的,則什麼也不做
template
inline
void
__destroy_aux
(forwarditerator, forwarditerator, _true_type)
//該元素的析構函式是non-trivial的,則依序呼叫其析構函式
template
inline
void
__destroy_aux
(forwarditerator first, forwarditerator last, _false_type)
//如果區間內的元素型別為char或wchar_t,則destroy什麼也不做
inline
void
destroy
(char*,
char*)
inline
void
destroy
(wchar_t*
, wchar_t*
)
stl使用了兩級記憶體分配,當申請記憶體較大時(大於128位元組)呼叫malloc()
分配記憶體。較小時從記憶體池中分配。
包裝介面
定義配置器時均使用此包裝介面定義。
//申請記憶體較大時直接使用malloc
//包裝介面,使用傳入的alloc分配記憶體,alloc預設第二級
template
class ******_alloc
static t*
allocate
(void
)static
void
deallocate
(t* p, size_t n)
static
void
deallocate
(t* p)
};
第一級分配器//申請記憶體較大時直接使用malloc
class malloc_alloc
static
void
*deallocate
(void
* p, size_t)
static
void
*reallocate
(void
* p, size_t, size_t new_sz)
};
第二級分配器
第二級配置器維護16個自由區塊鍊錶,分別管理8-128位元組的區塊,每次從適合的區塊中分配記憶體。
//第二級配置器
class default_alloc
;//區塊大小是8的倍數
enum
;//區塊最大大小
enum
;//自由區塊鍊錶個數
union obj
;static obj* free_list[nfreelists]
;static
char
* start_free;
static
char
* end_free;
static size_t heap_size;
static size_t round_up
(size_t bytes)
static size_t freelist_index
(size_t bytes)
static
void
*refill
(size_t n)
;//返回乙個物件並填充新的區塊
static
char
*chunk_alloc
(size_t size,
int& nobjs)
;//配置 nobjs * size 大小的空間
public:
static
void
*allocate
(size_t n)
;static
void
deallocate
(void
* p, size_t)
;static
void
*reallocate
(void
* p, size_t, size_t new_sz);}
;
這裡主要分析一下chunk_alloc()
函式
char
*default_alloc:
:chunk_alloc
(size_t size,
int&nobjs)
else
if(bytes_left >= size)
else
start_free =
(char*)
malloc
(bytes_to_get)
;//給記憶體池分配記憶體if(
0== start_free)
} end_free =0;
start_free =
(char
*)malloc_alloc:
:allocate
(bytes_to_get);}
heap_size +
= bytes_to_get;
end_free = start_free + bytes_to_get;
return
chunk_alloc
(size, nobjs);}
}
STL原始碼剖析 空間配置器
看過stl空間配置器的原始碼,總結一下 1 stl空間配置器 主要分三個檔案實現,stl construct.h 這裡定義了全域性函式construct 和destroy 負責物件的構造和析構。stl alloc.h檔案中定義了 一 二兩級配置器,彼此合作,配置器名為alloc.stl uninit...
STL原始碼剖析 空間配置器
allocator是空間配置器而不是記憶體配置器,空間不一定是記憶體,也可以是磁碟或其他輔助儲存介質。但sgi stl提供的配置器配置的物件是記憶體。sgi標準的空間配置器,std alloctor sgi定義了乙個符合部分標準,名為alloctor的配置器,效率不高,只把c 的 operator ...
STL原始碼剖析 空間配置器
我 然後開始聊vector動態擴容,o sgi stl的配置器與眾不同,名稱是alloc而非allocator。標準的allocator只是對操作符new和delete的一層薄薄的封裝,並沒有考慮到任何效率上的優化。一般而言,我們習慣的c 記憶體配置操作和釋放操作是這樣的 class foo foo...