zl程序教程

您现在的位置是:首页 >  大数据

当前栏目

SGI STL:空间配置器——第一级配置器:__malloc_alloc_template

配置 空间 __ STL Template malloc alloc
2023-09-27 14:29:24 时间

第一级配置器介绍

首先需要定义一个开关宏用来抛出异常,输出一个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