C++实战项目TinySTL之一:alloc.h

最近看了《STL源码剖析》和侯捷老师的STL课程,打算做一个小型的STL,在增加项目经验的同时也顺带复习STL和数据结构相关的知识。整个系列完全参考岚岚路的博客和github上的一个STL项目项目地址

任务

alloc.h作为STL六大部件之一的分配器有着举足轻重的作用,STL的思想将内存的分配释放与对象的构造和析构分离开来,分别在alloc.h和construct.h中实现。
alloc.h的主要思想:考虑到小型区块造成的内存碎片问题,STL设计了二级配置器,第一级直接使用malloc和free,第二级使用较为复杂的内存池。
内存池的示例如下:
在这里插入图片描述
alloc.h代码如下:

#ifndef _ALLOC_H_
#define _ALLOC_H_
#include<cstdlib>
namespace mySTL {
    
    
	class alloc {
    
    
	private:
		enum EAlign{
    
    ALIGN = 8};//小型区块的边界
		enum EMaxBytes{
    
    MAXBYTES=128};//上限,超过此大小直接使用malloc第一级分配器
		enum ENFreeLists{
    
    NFREELISTS=(EMaxBytes::MAXBYTES/EAlign::ALIGN) };//freelist个数,16
		enum ENObjs{
    
    NOBJS=20};//每次增添的节点数
	private:
		//freelists节点
		union obj {
    
    
			union obj *next; //指向下一块obj的指针
			char client[1];
		};
		static obj *free_list[ENFreeLists::NFREELISTS];//此处调用了上方的宏,只所以使用静态是为了让这部分唯一(不唯一则不安全)
	private:
		static char *start_free;//内存池的起始位置
		static char *end_free;//内存池的结束位置
		static size_t heap_size;//堆的大小
		//之所以在这里使用静态内存的原因也很清楚,这些数据都是唯一的,不可能同时存在两个,一旦改变(一般也不改变)就是全局一起改变
	private:
		//将byte上调至8的倍数
		static size_t ROUND_UP(size_t bytes) {
    
    
			return ((bytes + EAlign::ALIGN - 1) / EAlign::ALIGN);
		}
		//根据区块大小,决定使用第n号free-list,n从0开始计算
		static size_t FREELIST_INDEX(size_t bytes) {
    
    
			return (((bytes)+EAlign::ALIGN - 1) / EAlign::ALIGN - 1);
		}
		static void *refill(size_t n);
		
		//配置一大块空间,可容纳nobjs个大小为size的区块
		static char *chunk_alloc(size_t size, size_t& nojbs);
	public:
		//外部可以调用的部分
		static void *allocate(size_t bytes);
		static void deallocate(void *ptr, size_t bytes);
		static void *reallacate(void *ptr, size_t old_sz, size_t new_sz);
	};//静态方法效率上比实例化要高,这种经常要用的函数静态是最好了,每次实例化都要成本。
}
#endif

猜你喜欢

转载自blog.csdn.net/weixin_44537258/article/details/115055496