《STL原始碼剖析》 空間配置器(三)

2021-06-20 13:38:23 字數 2613 閱讀 4724

一、空間的配置與釋放,std::alloc

物件構造前的空間配置和物件析構後的空間釋放,由負責,sgi對此的設計哲學如下:

1. 向 system heap 要求空間。

2. 考慮多執行緒(multi-threads)狀態。

3. 考慮記憶體不足時的應變措施。

4. 考慮過多「小型區塊」可能造成的記憶體碎片(fragment)問題。

考慮到小型區塊所可能造成的記憶體破碎問題,sgi設計了雙層級配置器,第一級配置器直接使用 malloc() 和 free() ,第二級配置器則視情況採用不同的策略:當配置區塊超過 128 bytes時,視之為「足夠大」,便呼叫第一級配置器;當配置區塊小於 128 bytes時,視之為「過小」,為了降低額外負擔,便採用複雜的 memory pool 整理方式,而不再求助於第一級配置器。

在sgi的整個設計究竟只開放第一級配置器,或是同時開放第二級配置器,取決於 __use_malloc 是否被定義。

#ifdef  __use_malloc

...typedef __malloc_alloc_template<0> malloc_alloc;

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

#else

...// 令 alloc 為第二級配置器

typedef __default_alloc_template<__node_allocator_threads, 0> alloc;

#endif /* ! __use_malloc */

其中 __malloc_alloc_template 就是第一級配置器,__default_alloc_template 就是第二級配置器。sgi stl並未定義 __use_malloc,所以sgi使用第二級配置器。

sgi 還為 alloc 包裝了乙個介面如下,使配置器的介面能夠符合 stl 規格:

templateclass ******_alloc 

static t *allocate(void)

static void deallocate(t *p, size_t n)

static void deallocate(t *p)

};

其內部四個成員函式其實都是單純的轉呼叫,呼叫傳遞給配置器的成員函式。sgi stl容器全部使用這個 ******_alloc 介面。

二、第一級配置器 __malloc_alloc_template 剖析

// 注意,無"template型別引數"。至於"非型別引數"inst,則完全沒派上用場

template class __malloc_alloc_template

static void deallocate(void *p, size_t /* n */)

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

// 以下**c++的 set_new_handler()。換句話說,可以通過它

// 指定你自己的 out-of-memory handler

static void (* set_malloc_handler(void (*f)()))()

};// malloc_alloc out-of-memory handling

#ifndef __stl_static_template_member_bug

// 初值為 0。有待客端設定

template void (* __malloc_alloc_template::__malloc_alloc_oom_handler)() = 0;

#endif

template void * __malloc_alloc_template::oom_malloc(size_t n)

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

result = malloc(n); // 再次嘗試配置記憶體

if (result) return(result);

}}template void * __malloc_alloc_template::oom_realloc(void *p, size_t n)

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

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

if (result) return(result);

}}// 注意,以下直接將引數 inst 指定為 0

typedef __malloc_alloc_template<0> malloc_alloc;

第一級配置器以 malloc(),free(),realloc()等 c 函式執行實際的記憶體配置、釋放、重配置操作,並實現出類似 c++ new-handler 的機制。(所謂 c++ new handler 機制是,你可以要求系統在記憶體配置需求無法被滿足時,呼叫乙個你所指定的函式。換句話說,一旦 ::operator new 無法完成任務,在丟出 std::bad_alloc 異常狀態之前,會先呼叫由客端指定的處理例程。)

設計「記憶體不足處理例程」是客端的責任,設定「記憶體不足處理例程」也是客端的責任。

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原始碼剖析 空間配置器

由於物件的建立分為分配記憶體和呼叫建構函式兩部分,stl allocator使用alloc allocate 來分配記憶體,construct 構造物件。construct 函式只有乙個泛化的版本,destroy 函式有乙個泛化的針對迭代器的版本,destroy aux 根據是否需要呼叫析構函式進行...