STL学习_SGI空间配置器_第一级配置器源码分析

    这篇文章自己总结了下自己对于STL标准库中的SGI配置器的第一级配置器的源码分析,主要是想将自己上篇的理论知识具体化,

#ifndef _STL_ALLOC1_H
#define _STL_ALLOC1_H

#include <iostream>
#include <stdlib.h>
#include <exception>
#include <malloc.h>
using namespace std;

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

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;
        result = malloc(n);
        if(0 == result){
            result = oom_malloc(n);
        }
        return result;
    }

    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;
    }

    static void *deallocate(void *p, size_t)
    {
        free(p);
    }
    //设置异常处理函数
    //SGI不能直接使用c++的set_new_handler()函数,必须仿真一个类似的set_malloc_handler()
    //set_malloc_handler()这个函数传入的参数为[void (*f)()]是个函数指针,指的是下面写的程序test.cpp中
    //的my_new_handler()这个函数
    static void (*set_malloc_handler(void (*f)()))()
    {
        void (*old)() = __malloc_alloc_oom_handler;
        __malloc_alloc_oom_handler = f;
       return (old);
    }
};

//这里将__malloc_alloc_oom_handler()设置为0,有待客户设置自己想要的异常处理函数。
template<int inst>
void (*__malloc_alloc_template<inst>::__malloc_alloc_oom_handler)() = 0;

//当allocate()申请空间失败的情况下会调用oom_malloc()这个函数,这个函数会不断的尝试空间的释放,
//和客户空间的申请,如果客户自己定义了内存异常处理函数(my_malloc_handler())则当内存申请失败
//会调用异常处理函数,如果客户没有自己定义异常处理函数,则抛出一个异常。
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;//抛出一个异常,并利用exit(1)函数硬生生的终止程序
        }
        //如果设置了,则调用客户自己定义的异常处理函数
        (*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 = malloc(n);
        if(0 == result){
            return result;
        }
    }
}

typedef __malloc_alloc_template<0> malloc_alloc; 

#endif

测试程序:

#include "stl_alloc1.h"

void my_new_handler()
{
    cout<<"out of memory"<<endl;
}

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;
}

申请的空间大小为4*10,结果系统能够给客户申请这么大的空间申请成功,如果改成sizeof(int)*100000000000000即申请一个很大的空间,系统就没有足够大的空间供客户申请,则由于malloc()申请不到空间,则会调用oom_alloc()函数,但是由于客户需求的空间太大oom_alloc()也申请不到空间,则oom_alloc()函数内部处于死循环阶段不断的调用异常处理函数my_new_handler(),不断的进行空间的申请,所以结果是屏幕上不断的打印out of memory

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值