一级配置器
一级配置器的类. 它无template型别参数. 这里我将public定义的函数和私有成员函数成对分离出来讲解
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| template <int inst> class __malloc_alloc_template { private: static void *oom_malloc(size_t); static void *oom_realloc(void *, size_t); #ifndef __STL_STATIC_TEMPLATE_MEMBER_BUG static void ( *__malloc_alloc_oom_handler)(); #endif public: };
|
唯一比较麻烦的就是set_malloc_handler 它就是接受一个函数指针, 用来保存用户自定义的处理函数, 如果用户没有设置的话, 默认就设置为0. 因为处理函数会跟后面的内存不足有关系
1 2 3 4 5 6
| static void (*set_malloc_handler(void (*f)()))() { void (*old)() = __malloc_alloc_oom_handler; __malloc_alloc_oom_handler = f; return (old); }
|
默认将处理例程设置为0, 只有用户自己设置
1 2
| template <int inst> void (* __malloc_alloc_template<inst>::__malloc_alloc_oom_handler)() = 0;
|
allocate
allocate : 很明显, 这里直接调用malloc分配内存, 当内存不足的时候, 程序继续调用oom_malloc来选择抛出异常还是一直申请内存, 直到申请内存成功.
1 2 3 4 5 6 7
| static void *allocate(size_t n) { void *result = malloc(n); if (0 == result) result = oom_malloc(n); return result; }
|
oom_malloc函数功能 : 除非用户自定义了处理例程, 否则当内存不足的时候直接输出内存不足的提示然后直接调用exit(1);
用户定义了处理程序, 函数会一直进行内存申请, 直到申请到内存为止
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| template <int inst> void *__malloc_alloc_template<inst>::oom_malloc(size_t n) { void (*my_malloc_handler)(); void *result; for (;;) { my_malloc_handler = __malloc_alloc_oom_handler; if (0 == my_malloc_handler) { __THROW_BAD_ALLOC; } (*my_malloc_handler)(); result = malloc(n); if (result) return (result); } }
|
deallocate
一级配置器直接调用free释放内存
1
| static void deallocate(void *p, size_t ) { free(p); }
|
reallocate
下面的函数都是很简单的或是重复的功能, 就一笔带过.
这里reallocate和oom_realloc和上面allocate一样的, 这里就不做过多的解释了.
1 2 3 4 5 6
| static void *reallocate(void *p, size_t , size_t new_sz) { void *result = realloc(p, new_sz); if (0 == result) result = oom_realloc(p, new_sz); return result; }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| template <int inst> void *__malloc_alloc_template<inst>::oom_realloc(void *p, size_t n) { void (*my_malloc_handler)(); void *result;
for (;;) { my_malloc_handler = __malloc_alloc_oom_handler; if (0 == my_malloc_handler) { __THROW_BAD_ALLOC; } (*my_malloc_handler)(); result = realloc(p, n); if (result) return (result); } }
|
程序默认定义mallo_alloc函数, 并且设置统一的调用接口, 默认的的接口为第二级配置器
1 2
| typedef __malloc_alloc_template<0> malloc_alloc;
|
统一的接口
定义符合STL规格的配置器接口, 不管是一级配置器还是二级配置器都是使用这个接口进行分配的
1 2 3 4 5 6 7 8 9 10 11 12 13 14
|
template <class T, class Alloc> class simple_alloc { public: static T *allocate(size_t n) { return 0 == n ? 0 : (T *)Alloc::allocate(n * sizeof(T)); } static T *allocate(void) { return (T *)Alloc::allocate(sizeof(T)); } static void deallocate(T *p, size_t n) { if (0 != n) Alloc::deallocate(p, n * sizeof(T)); } static void deallocate(T *p) { Alloc::deallocate(p, sizeof(T)); } };
|
STL对malloc和free用函数重新进行了封装, 同时一级还是二级都做了统一的接口. 接下来我们继续分析第二级配置器.