STL原始碼剖析 空間配置器

2021-08-28 21:03:54 字數 3625 閱讀 1138

由於物件的建立分為分配記憶體和呼叫建構函式兩部分,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...