@bit::Shadow
✧(≖ ◡ ≖✿
目录
定长内存池
有效、可分配内存块有两部分
1.有效内存池块。
2.自由链表管理区域。
构造函数
划分128kB给ObjectPool对象,异常抛出std::bad_alloc()。
New:为特定类型通过自由链表存储的/池内,分配固定空间大小。
Delete(const T* t):销毁指定目标。
一:New()的初步设计

_remainBytes:内存块内(自由链表内不计入大小)的剩余字节。
cpp
//申请
T* New()
{
int _sz = sizeof(T);
//块内分配
if (_remainBytes <= _sz)
{
//剩余不足,新开大块
Alloc();//内存碎片问题不计
}
T* obj = (T*)_memory;
_memory += _sz;
_remainBytes -= _sz;
return obj;
}
初步架构:
cpp
template<typename T>
class ObjectPool//无并发性,外界统一接口?
{
private:
void Alloc()//bool?抛异常与bool分隔。bool会增加处理成本
{
//划分块
_memory = (char*)malloc(128 * 1024);//1.此处malloc不够纯粹,"其底层封装"(划掉)
//※ //2.使用SystemAlloc更纯粹,后期对比效率时替换
if (!_memory)
throw std::bad_alloc();//大块划分失败,怎么捕捉?与构造函数无关?
_remainBytes = 128 * 1024;//※
}
public:
ObjectPool()
:_memory(nullptr), _remainBytes(0)
{
Alloc();
}
//**成员先走初始化列表,后走函数体内**
//申请
T* New()
{
int _sz = sizeof(T);
//块内分配
if (_remainBytes <= _sz)
{
//剩余不足,新开大块
Alloc();//内存碎片问题不计
}
T* obj = (T*)_memory;
_memory += _sz;
_remainBytes -= _sz;
return obj;
}
private:
char* _memory;//内存块头指针(128kB)
int _remainBytes;//内存块内(自由链表内不计入大小)的剩余字节
};
二:Delete()的设计
被删除任务删除头插进自由链表,由_freeList管理。
为什么不回退_memory?
销毁对象内存不一定连续。
设计图示

cpp
//释放,自由链表回收♻️
void Delete(const T* t)
{
//头插
*(void**)t = _freeList;
//_freeList = t;//原因分析
_freeList = const_cast<T*>(t);
}
✨亮点:
1.为兼容x64、x86系统使用指针这一随系统大小变换的类型作为,限制访问区域。
2.const_cast<template T> (T t); 去const属性 // 非std域!!
完整代码gitee
cpp
#pragma once
//using namespace std::
#include<iostream>
/*
设计原则:
1.模板元编程。基于T大小申请、管理内存块。
意味着:
单一类型对象,New固定T大小无法指定。不像(void*) maollc(sizeof(size_t size))
2.定长内存池设计的目标是:体会"池化技术",这一高效、广泛应用技术的底层设计原理。
//严格遵循"高内聚,低耦合"特性
*/
template<typename T>
class ObjectPool//无并发性
{
private:
void Alloc()//bool?抛异常与bool分隔。bool会增加处理成本
{
//划分块
_memory = (char*)malloc(128 * 1024);//1.此处malloc不够纯粹,"其底层封装"(划掉)
//※ //2.使用SystemAlloc更纯粹,后期对比效率时替换
if (!_memory)
throw std::bad_alloc();//大块划分失败,怎么捕捉?与构造函数无关?
_remainBytes = 128 * 1024;//※
}
T* FreeAlloc()
{
//自由链表分配
//if (!_freeList)//err
if (_freeList)
{
T* obj = _freeList;
//头删
_freeList = *(void**)_freeList;
_remainBytes = _remainBytes;
return obj;
}
return nullptr;
}
public:
ObjectPool()
:_memory(nullptr), _remainBytes(0), _freeList(nullptr)
{
Alloc();
}
//**成员先走初始化列表,后走函数体内**
//申请
T* New()
{
//1.自由链表分配
return FreeAlloc();
//int _sz = sizeof(T);因为自由链表要管理,所以至少给4/8
int _sz = sizeof(T) >= sizeof(T*) ? sizeof(T) : sizeof(T*);
//dpsk:一个类型T*的指针管理T的空间与管理4T空间有什么区别?
// 访问限制、算术法固定
//2.块内分配
if (_remainBytes <= _sz)
{
//剩余不足,新开大块
Alloc();//内存碎片问题不计
}
T* obj = (T*)_memory;//
_memory += _sz;
_remainBytes -= _sz;
return obj;
}
//释放,自由链表回收♻️
void Delete(const T* t)
{
//头插
*(void**)t = _freeList;
//_freeList = t;//原因分析
_freeList = const_cast<T*>(t);
}
private:
char* _memory;//内存块头指针(128kB)
int _remainBytes;//内存块内(自由链表内不计入大小)的剩余字节
T* _freeList;//自由链表头
};
//测试类型T
class TreeNode
{
private:
int _val;
TreeNode* _left;
TreeNode* _right;
};
感谢支持,长期连载
欢迎关注
