美文网首页程序员
STL内存分配器详解之__malloc_alloc_templa

STL内存分配器详解之__malloc_alloc_templa

作者: Jesson3264 | 来源:发表于2018-10-10 09:49 被阅读0次
    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

    相关文章

      网友评论

        本文标题:STL内存分配器详解之__malloc_alloc_templa

        本文链接:https://www.haomeiwen.com/subject/qpnuaftx.html