對於分配器的要求,應滿足c++標準中的幾個函式:
1.分配器應是乙個模板類,設型別為t
2.模板類物件應有public:t* allocate(int n)功能,分配一段長為至少為n*typesize的記憶體(原始,未構造)儲存n個型別為t的物件,返回指向分配記憶體頭部的t型別指標
3.應該有deallocate(p,n),其中p為上述t型別指標,n不能是任意的數字,應與分配時的n大小相同;
4.應有建構函式,construct(p,arg),目的是呼叫型別t的建構函式
5.應有destroy(p),只析構p指向的物件。
大前提是已知:記憶體從**來?答:malloc來的
乙個很重要的思想就是,如何合理的使用malloc和free,也就是說,分配的思想到最後,就是傳乙個byte_size到malloc裡,但是除此之外:
1.我們需要呼叫建構函式來構造,而且建構函式應有過載寫法,即迭代器區間寫法
2.我們需要呼叫析構函式,而且析構函式應有過載寫法,即迭代器區間寫法
3.out of memory處理(oom)
我們將儲存看為四部分,1.已經使用的;2.freelist(根據索引freelist_index[i]來獲取,每個索引解引用後是指向obj(記憶體塊)型別的指標,索引下是乙個又乙個的鍊錶);3.記憶體池(乙個較大空間,從start到end,用兩個char指標來維護)4.大儲存(malloc就是從這部分取);原始碼剖析中sgi以128byte為區分;根據需求,2和4中進行選擇。
簡單理解:使用者申請記憶體:
如果大於128bytes,直接malloc,申請不到直接oom處理,稱之為第一級配置器
如果小於128bytes,去查詢freelist,索引下記憶體空間為0,從記憶體池申請,能滿足多少塊兒申請多少
實在乙個塊都申請不到,剩下的小於乙個塊的大小,也不能浪費了,直接編入freelist_index[bytes_left],這裡bytes_left是以8bytes為單位不是1bytes,隨後就得從儲存裡malloc了,malloc出兩倍所需空間給記憶體池,malloc失敗的話,再從freelist裡**足夠大的記憶體。
底下把書中分散開的1-2級配置器整理了起來,並對一些**進行了解釋
#pragma once
#include//一二級配置器
#ifdef _use_malloc
typedef _malloc_alloc_template<0> malloc_alloc;
typedef malloc_alloc alloc;
#else
typedef _default_alloc_template<_node_allocator_threads, 0> alloc;
#endif
templateclass ******_alloc
static t*allocate(void)
static void deallocate(t *p, size_t n)
static void deallocate(t*p)
};//level_1_alloc
template//non-type temp parameter
class _malloc_alloc_template
static void deallocate(void*p, size_t)
static void*reallocate(void*p, size_t old_size, size_t new_size)
static void(*set_malloc_handler(void(*f)()))()
};templatevoid(*_malloc_alloc_template::_malloc_alloc_oom_handler)() = 0;
templatevoid*_malloc_alloc_template::oom_malloc(size_t n)
(*my_malloc_handler)();
result = malloc(n);
if (result)return (result); }}
templatevoid*_malloc_alloc_template::oom_realloc(void*p, size_t n)
(*my_malloc_handler)();
result = realloc(p, n);
if (result) return (result); }}
//level_2_alloc
enum;
enum;
enum;
template//多執行緒
class _default_alloc_template
union obj ;
static obj*volatile free_list[_nfreelists] = ;
static size_t freelist_index(size_t bytes)
static void*refill(size_t n);
static char*chunk_alloc(size_t size, int &nobjs);
static char*start_free=0;//代表記憶體池的空間
static char*end_free=0;
static size_t heap_size=0;//chunk 部分,代表記憶體池起始截止和大小
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 = 0;
start_free = (char*)malloc_alloc::allocate(bytes_to_get);//這一步就是垂死掙扎,希望第一級配置器可以通過oom機制盡力
}heap_size += bytes_to_get;
end_free = start_free + bytes_to_get;
return(chunk_alloc(size, nobjs));
} }void*refill(size_t n)
else
} return (result);
}public:
static void*allocate(size_t n)
*my_free_list = free_list + freelist_index(n);
result = *my_free_list;
if (result == 0)
*my_free_list = result->free_list_link;
return result;
} static void deallocate(void*p, size_t n)
static void*reallocate(void*p, size_t old_size, size_t new_size)
};
STL原始碼剖析 分配器Allocators
new 指我們在c 裡通常用到的運算子 operator new 指對new的過載形式,它是乙個函式,並不是運算子 函式operator new中呼叫malloc 進行記憶體分配。malloc實際記憶體分配得到的記憶體空間如下 new 運算子執行過程 呼叫operator new分配記憶體 可過載 ...
STL的記憶體分配器
題記 記憶體管理一直是c c 程式的 關於記憶體管理的話題,大致有兩類側重點,一類是記憶體的正確使用,例如c 中new和delete應該成對出現,用raii技巧管理記憶體資源,auto ptr等方面,很多c c 書籍中都使用技巧的介紹。另一類是記憶體管理的實現,如linux核心的slab分配器,st...
STL的記憶體分配器
分類 c c stl 2011 04 04 18 34 1689人閱讀收藏 舉報list 演算法vector linux核心 byte raii 題記 記憶體管理一直是c c 程式的 關於記憶體管理的話題,大致有兩類側重點,一類是記憶體的正確使用,例如c 中new和delete應該成對出現,用rai...