第一级配置器介绍
首先需要定义一个开关宏用来抛出异常,输出一个oom信息。
namespace Srh
{
#if 0
#include<new>
#define __THROW_BAD_ALLOC throw std::bad_alloc;
#elif !defined(__THROW_BAD_ALLOC)
#define __THROW_BAD_ALLOC std::cerr << "out of memory" << std::endl; exit(1);
#endif
}
类模板为:
// 第一级配置器
template<int inst>
class __malloc_alloc_template {};
方法
第一级配置器的方法,直接调用malloc,free,realloc,如果出现内存不足的情况,就交给私有方法(oom__)处理。
public:
using PFUN = void (*)();
public:
static void* allocate(size_t n) // malloc
static void deallocate(void* p, size_t n); //free
// realloc
static void* reallocate(void* p, size_t old_sz, size_t new_sz);
//static void (*set_malloc_handler(void (*f))();
static PFUN set_malloc_handler(PFUN p)
private:
static void* omm_malloc(size_t n);
static void* oom_realloc(void* p, size_t new_sz);
//static void(*__malloc_alloc_oom_handler)();
static PFUN __malloc_alloc_oom_handler;
源码
#ifndef MY_ALLOC_H
#define MY_ALLOC_H
#include<iostream>
namespace Srh
{
#if 0
#include<new>
#define __THROW_BAD_ALLOC throw std::bad_alloc;
#elif !defined(__THROW_BAD_ALLOC)
#define __THROW_BAD_ALLOC std::cerr << "out of memory" << std::endl; exit(1);
#endif
// 第一级配置器
template<int inst>
class __malloc_alloc_template
{
public:
using PFUN = void (*)();
private:
// 处理内存不足问题
static void* oom_malloc(size_t n)
{
void* result = nullptr;
void (*my_malloc_handler) () = nullptr;
// 要么得到空间,要么终止程序
for (; ;) // 不断尝试 释放、配置、再释放、再配置...
{
my_malloc_handler = __malloc_alloc_oom_handler;
if (nullptr == my_malloc_handler)
{
__THROW_BAD_ALLOC;
}
my_malloc_handler(); //调用处理例程,企图释放内存
result = malloc(n); // 再次尝试配置内存
if (nullptr != result)
{
return result;
}
}
}
static void* oom_realloc(void* p, size_t new_sz)
{
void* result = nullptr;
void (*my_malloc_handler) () = nullptr;
// 要么得到空间,要么终止程序
for (; ;) // 不断尝试 释放、配置、再释放、再配置...
{
my_malloc_handler = __malloc_alloc_oom_handler;
if (nullptr == my_malloc_handler)
{
__THROW_BAD_ALLOC;
}
my_malloc_handler(); //调用处理例程,企图释放内存
result = realloc(p, new_sz); // 再次尝试配置内存
if (nullptr != result)
{
return result;
}
}
}
//static void(*__malloc_alloc_oom_handler)();
static PFUN __malloc_alloc_oom_handler;
public:
static void* allocate(size_t n)
{
void* result = malloc(n); // malloc
if (nullptr == result)
{
// 无法满足需求,采用oom_malloc
result = oom_malloc(n);
}
return result;
}
static void deallocate(void* p, size_t n)
{
free(p); // free
}
static void* reallocate(void* p, size_t old_sz, size_t new_sz)
{
void* result = realloc(p, new_sz); // realloc
if (nullptr == result)
{
// 无法满足需求,采用oom_realloc
result = oom_realloc(p, new_sz);
}
return result;
}
//static void (*set_malloc_handler(void (*f))();
static PFUN set_malloc_handler(PFUN p)
{
PFUN old = __malloc_alloc_oom_handler;
__malloc_alloc_oom_handler = p;
return old;
}
};
/*
template<int inst>
void(*__malloc_alloc_template<inst>::__malloc_alloc_oom_handler)() = nullptr;
*/
template<int inst>
typename __malloc_alloc_template<inst>::PFUN
__malloc_alloc_template<inst>::__malloc_alloc_oom_handler = nullptr;
// 将参数inst置为0
using malloc_alloc = __malloc_alloc_template<0>;
}
#endif