前言
在STL中,容器的定义中都带一个模板参数,如vector
template <class T, class Alloc = alloc> class vector {...}
其中第二个参数就是该容器使用的空间配置器,其中缺省使用STL已经实现的空间配置器(alloc),
该配置器使用malloc/free等为vector分配内存。
缺省的空间配置器
alloc定义了两级的空间配置器,第一级是对malloc/free简单的封装。
而为了解决内存碎片的问题,跟进行内存管理,alloc实现的第二级的空间配置器。
第二级空间配置器在分配大块内存(大于128bytes)时,会直接调用第一级空间配置器,
而分配小于128bytes的内存时,则使用内存池跟free_list进行内存分配/管理。
第一级空间配置器
基本实现如下(跟SGI STL可能有点出入,主要是提取核心的内容)
1 class base_alloc { 2 public: 3 // 只是对malloc/free的简单封装 4 static void* allocate(size_t n) 5 { 6 void* res = malloc(n); 7 if (0 == res) res = oom_malloc(n); 8 return res; 9 } 10 static void* reallocate(void* p, size_t new_sz) 11 { 12 void* res = realloc(p, new_sz); 13 if (0 == res) res = oom_realloc(p, new_sz); 14 return res; 15 } 16 static void deallocate(void* p) 17 { 18 free(p); 19 } 20 // 用来设置内存不足时的处理函数 该函数参数跟返回值都是一个函数指针 21 // 一般会抛出异常/尝试回收内存 22 static void(*set_handler(void(*f)()))() 23 { 24 void(*old)() = _oom_handler; 25 _oom_handler = f; 26 return old; 27 } 28 private: 29 // 用来处理内存不足的情况 30 static void* oom_malloc(size_t n) 31 { 32 void(*my_handler)(); 33 void* res; 34 35 for (;;) 36 { 37 my_handler = _oom_handler; 38 if (0 == my_handler) { return NULL; } 39 (*my_handler)(); 40 if (res = malloc(n)) return res; 41 } 42 } 43 // 用来处理内存不足的情况 44 static void* oom_realloc(void* p, size_t n) 45 { 46 void(*my_handler)(); 47 void* res; 48 49 for (;;) 50 { 51 my_handler = _oom_handler; 52 if (0 == my_handler) { return NULL; } 53 (*my_handler)(); 54 if (res = reallocate(p, n)) return res; 55 } 56 } 57 // 由用户设置,在内存不足的时候进行处理,由上面两个函数调用 58 static void(*_oom_handler)(); 59 }; 60 61 // 处理函数默认为0 62 void(*base_alloc::_oom_handler)() = 0;