程序员

STL内存分配器详解之__malloc_alloc_templa

2018-10-10  本文已影响0人  Jesson3264
typedef __malloc_alloc_template<0> malloc_alloc;

从这里可以看出malloc_alloc其实是__malloc_alloc_template的别名,找到__malloc_alloc_template的定义:

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:
        static void * allocate(size_t n)
        {
            void *result = malloc(n);
            if (0 == result) result = 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 = 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);
        }
};


#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>::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);
    }
}

为了让代码简洁,这个地方删掉了一些空格。
allocate被调用时,直接调用的是系统接口malloc,如果获取内存失败会去调用oom_malloc函数,先去调用内存分配不足的一个处理函数,然后再次尝试分配内存。不断的循环。如果没有自己定义my_malloc_handler函数,会执行__THROW_BAD_ALLOC宏。

#if 0
#   include <new>
#   define __THROW_BAD_ALLOC throw bad_alloc
#elif !defined(__THROW_BAD_ALLOC)
#   include <iostream.h>
#   define __THROW_BAD_ALLOC cerr << "out of memory" << endl; exit(1)
#endif

直接打印错误,然后exit(1)强制杀死的程序。这样很危险,那么问题来了。

怎么设置自己的内存分配不足时的错误处理函数

void my_new_handler()
{    
  cout<<"out of memory"<<endl;
  //to do , delete some memory.
} 
int main(int argc, char **argv)
{    
    __malloc_alloc_template<0>::set_malloc_handler(my_new_handler);    
    int *p = (int *)__malloc_alloc_template<0>::allocate(sizeof(int) * 10);    
    *p = 100;    
    cout<<*p<<endl;    
    __malloc_alloc_template<0>::deallocate(p, 0);    
    return 0;
}

可以讲10改成一个更大的数,这样就会触发自己定义的内存不足处理函数。

下一章:STL内存分配器详解之__default_alloc_template

上一篇下一篇

猜你喜欢

热点阅读