STL源码学习之一级空间配置器
一级空间配置器
源码:
#if 0
# include <new>
# define __THROW_BAD_ALLOC throw bad_alloc
#elif !defined(__THROW_BAD_ALLOC)
# include <iostream>
# define __THROW_BAD_ALLOC cerr << "out of memery" << endl; exit(1);
#endif
// malloc-based allocator.通常比稍后介绍的 default alloc 速度慢
// 一般而言是thread-safe,并且对于空间的运用比较高效
// 以下是第一级配置器
// 注意,无“template型别参数”。置于“非型别参数”inst,则完全没排上用场
template <int inst>
class __malloc_alloc_template {
private:
//以下都是函数指针,所代表的函数将用来处理内存不足的情况
static void *oom_malloc(size_t);
static void *oom_realloc(void*, size_t);
static void (* __malloc_alloc_oom_handler)();
public:
static void * allocate(size_t n) {
void *result = malloc(n); // 第一级配置器直接使用malloc
// 无法满足需求时,改用oom_malloc
if (0 == result) result = oom_malloc(n);
return result;
}
static void deallocate(void *p, size_t /* n */) {
free(p); // 第一级配置器直接用free()
}
static void * reallocate(void *p, size_t /* old_sz */, size_t new_sz) {
void *result = realloc(p, new_sz);
if (0 == result) result = oom_realloc(p, new_sz);
return result;
}
// 以下仿真C++的 set_handler()。换句话,你可以通过它
// 指定自己的 out-of-memory handler,企图释放内存
// 因为没有调用 new,所以不能用 set_new_handler
static void (* set_malloc_handler(void (*f)())) () {
void (*old)() = __malloc_alloc_oom_handler;
__malloc_alloc_oom_handler = f;
return old;
}
};
// 初值为0,待定
template <int inst>
void (* __malloc_alloc_template<inst>::__malloc_alloc_oom_handler)() = 0;
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;
}
}
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;
}
其中oom_malloc,当malloc失败时,这个函数就被调用。它的作用就是去调用用户自定义的释放空间的一个函数__malloc_alloc_oom_handler,不断的去释放空间,直到可以申请空间为止,如果实在不成功就会抛出异常,结束程序
oom_realloc和oom_malloc大同小异,几乎是一样的。惟一的区别在于前者是realloc申请空间,后者是malloc申请空间
typedef void (*FUNC)() ,FUNC是一种类型,它定义的变量是指向函数的指针。
就相当于static FUNC set_malloc_handler(FUNC f) 说白了,就是一个函数它的参数是个指针,它的返回值也是个指针,就这样!!!
如果细一点说,那么参数和反回值都是指向函数的指针。