前言

在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;
View Code

相关文章: