您的位置:首页 > 其它

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

2016-04-25 21:56 645 查看
这篇文章自己总结了下自己对于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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: