- template<class _Tp, class _Alloc>
- class simple_alloc {
- public:
- static _Tp* allocate(size_t __n)
- { return 0 == __n ? 0 : (_Tp*) _Alloc::allocate(__n * sizeof (_Tp)); }
- static _Tp* allocate(void)
- { return (_Tp*) _Alloc::allocate(sizeof (_Tp)); }
- static void deallocate(_Tp* __p, size_t __n)
- { if (0 != __n) _Alloc::deallocate(__p, __n * sizeof (_Tp)); }
- static void deallocate(_Tp* __p)
- { _Alloc::deallocate(__p, sizeof (_Tp)); }
- };
可以看到是根据第二个类型参数_Alloc调用它的static函数来完成内存分配的。其实主要就是用的
template
template
先看看__malloc_alloc_template代码,因为它要比较简单一些:
- template <int __inst>
- class __malloc_alloc_template {
- private:
- static void* _S_oom_malloc(size_t);
- static void* _S_oom_realloc(void*, size_t);
- #ifndef __STL_STATIC_TEMPLATE_MEMBER_BUG
- static void (* __malloc_alloc_oom_handler)();
- #endif
- public:
- static void* allocate(size_t __n)
- {
- void* __result = malloc(__n);
- if (0 == __result) __result = _S_oom_malloc(__n);
- return __result;
- }
- static void deallocate(void* __p, size_t /* __n */)
- {
- free(__p);
- }
- static void* reallocate(void* __p, size_t /* old_sz */, size_t __new_sz)
- {
- void* __result = realloc(__p, __new_sz);
- if (0 == __result) __result = _S_oom_realloc(__p, __new_sz);
- return __result;
- }
- static void (* __set_malloc_handler(void (*__f)()))()
- {
- void (* __old)() = __malloc_alloc_oom_handler;
- __malloc_alloc_oom_handler = __f;
- return(__old);
- }
- };
- // malloc_alloc out-of-memory handling
- #ifndef __STL_STATIC_TEMPLATE_MEMBER_BUG
- template <int __inst>
- void (* __malloc_alloc_template<__inst>::__malloc_alloc_oom_handler)() = 0;
- #endif
- template <int __inst>
- void*
- __malloc_alloc_template<__inst>::_S_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>::_S_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);
- }
- }
allocate/reallocate就是分配内存的函数了,它调用malloc/realloc进行分配,如果不成功就调用_S_oom_malloc/S_oom_realloc(oom应该就是out of memory的意思)函数重新进行分配,但是它有一个前提就是设置了初始给函数指针__malloc_alloc_oom_handler赋了值。默认的动作是__THROW_BAD_ALLOC。
- #ifndef __THROW_BAD_ALLOC
- # if defined(__STL_NO_BAD_ALLOC) || !defined(__STL_USE_EXCEPTIONS)
- # include <stdio.h>
- # include <stdlib.h>
- # define __THROW_BAD_ALLOC fprintf(stderr, "out of memory\n"); exit(1)
- # else /* Standard conforming out-of-memory handling */
- # include <new>
- # define __THROW_BAD_ALLOC throw std::bad_alloc()
- # endif
- #endif
static void (* __set_malloc_handler(void (*__f)()))() 就是设置__malloc_alloc_oom_handler指针的函数,它看起来比较复杂,其实分析出来就是它的参数和返回值都是一个不接收任何参数并且返回值为void的函数指针。通过它给_malloc_alloc_oom_handler赋值,遇到malloc/realloc分配失败的时候就会先执行这个函数,并重新尝试分配(当然前提是函数没有退出……)