STL之空間配置器

2021-09-17 21:16:35 字數 4018 閱讀 3281

#pragma once

#include//為了malloc、free

#include#define __throw_bad_alloc std::cerr<

class onespce

// 對free的封裝

static void deallocate(void *p, size_t /* n */) //這個size_t完全可以不要,但是為了統一介面,加上了這個size_t

// 對realloc的封裝---該函式基本不用

static void * reallocate(void *p, size_t /* old_sz */, size_t new_sz)

// 模擬set_new_handle

// 該函式的引數為函式指標,返回值型別也為函式指標

// void (* set_malloc_handler( void (*f)() ) )()

typedef void(*pfunc)();

static pfunc set_malloc_handler(pfunc f)

//static void(*set_malloc_handler(void(*f)()))() };

void(*onespce::__malloc_alloc_oom_handler)() = 0; //如果沒有設定的話,在下面的函式就只能會拋異常

// malloc申請空間失敗時代用該函式

void * onespce::oom_malloc(size_t n)

// 如果設定,執行使用者提供的空間不足應對措施

(*my_malloc_handler)();

// 繼續申請空間,可能就會申請成功

result = malloc(n);

if (result)

return(result); }}

// 類似oom_malloc

void* onespce::oom_realloc(void *p,size_t n)

(*my_malloc_handler)(); //呼叫處理例程,企圖釋放記憶體

result = realloc(p, n); //再次嘗試設定記憶體

if (result)

return(result);

}}

class __default_alloc_template

; // 如果使用者所需記憶體不是8的整數倍,向上對齊到8的整數倍

enum ; // 大小記憶體塊的分界線

enum ; // 採用雜湊桶儲存小塊記憶體時所需桶的個數

// 如果使用者所需記憶體塊不是8的整數倍,向上對齊到8的整數倍

static size_t round_up(size_t bytes)

private:

// 用聯合體來維護鍊錶結構----下面解釋

union obj

;private:

static obj * free_list[__nfreelists];

// 雜湊函式,根據使用者提供位元組數找到對應的桶號

static size_t freelist_index(size_t bytes)

// start_free與end_free用來標記記憶體池中大塊記憶體的起始與末尾位置

static char *start_free;

static char *end_free;

// 用來記錄該空間配置器已經想系統索要了多少的記憶體塊

static size_t heap_size;

// ...

} ;char* twospace::start_free = 0;

char* twospace::end_free = 0;

size_t twospace::heap_size = 0;

twospace::obj* twospace::free_list[__nfreelists] = ;

union obj

;

空間配置函式和空間釋放函式
static void * allocate(size_t n)

// 根據使用者所需位元組找到對應的桶號

my_free_list = free_list + freelist_index(n);

result = *my_free_list;

// 如果該桶中沒有記憶體塊時,向該桶中補充空間

if (result == 0)

// 維護桶中剩餘記憶體塊的鏈式關係

// 函式功能:使用者將空間歸還給空間配置器

static void deallocate(void *p, size_t n)

// 找到對應的雜湊桶,將記憶體掛在雜湊桶中

重新填充 free list

// 函式功能:向雜湊桶中補充空間

// 引數n:小塊記憶體位元組數

static void* refill(size_t n)

else

}return(result);

}

記憶體池
static char* 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置空,因為一級空間配置器一旦拋異常就會出問題

end_free = 0;

start_free = (char*)onespce::allocate(bytes_to_get);

}// 通過系統堆向記憶體池補充空間成功,更新資訊並繼續分配

heap_size += bytes_to_get;

end_free = start_free + bytes_to_get;

return(chunk_alloc(size, nobjs));

} }

// 向系統堆求助,往記憶體池中補充空間

// 計算向記憶體中補充空間大小:本次空間總大小兩倍 + 向系統申請總大小/16

size_t bytes_to_get = 2 * total_bytes + round_up(heap_size >> 4);

空間配置器的預設選擇
#ifdef __use_malloc

typedef __malloc_alloc_template<0> malloc_alloc;

typedef malloc_alloc alloc; //令alloc 為一級配置器

#else

typedef __default_alloc_template<__node_allocator_threads> alloc;

#endif // !__use_malloc

STL之空間配置器

空間配置器allocator負責空間的配置和管理,是一種實現了動態空間配置 空間管理 空間釋放的class template。1.空間配置器的標準介面 allocator value type allocator pointer allocator const pointer allocator r...

STL之空間配置器

最近在看侯捷老師寫的stl原始碼剖析,想通過看優秀的 來提高自己的程式設計水平。首先stl提供了六大元件,彼此可以套用使用。借助一張從書上截的圖來表明 container通過allocator來獲取資料儲存空間 algorithms通過迭代器來獲取container的內容,functors可以協助a...

STL 空間配置器

stl有6大元件 容器 演算法 迭代器 仿函式 配接器 分配器。它們之間的密切關係是stl的精髓所在,容器用來存放資料,而容器存在的前提是要有分配器給它分配記憶體,接下來需要實現演算法,迭代器便作為演算法來對容器資料操作的橋梁,演算法可以使用仿函式完成不同的策略變化,配接器可修飾或套接仿函式。說了麼...