《STL原始碼剖析》之分配器

2021-09-11 08:24:00 字數 3711 閱讀 9222

對於分配器的要求,應滿足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...