这个内存池只是一个demo版实现,主要以下四个核心要素:
- 每个内存对象大小固定
- 使用链表来维护空闲节点,线程池维护一个head指针
- 使用链表的头插法实现将空闲节点插入到head实现free
- 重载使用线程池类的
void * operator new(size_t)
和void free(void*p)
函数
这个实现存在的问题:
- 内存池的空间释放
- 需要为每个类定义一个线程池对象
- 多线程安全问题
#include <iostream>
using namespace std;
template <int ObjectSize, int Num>
class Mempool
{
public:
struct FreeNode
{
FreeNode *next;
char data[ObjectSize];
};
// 核心数据结构就是一个链表
FreeNode *freeHead;
Mempool()
{
cout << "初始化空间" << endl;
FreeNode *p = new FreeNode[Num];
for (int i = 0; i < Num - 1; i++)
{
p[i].next = &p[i + 1];
}
p[Num - 1].next = NULL;
freeHead = p;
}
~Mempool()
{
// 需要注意的是, 这个实现对于申请新空间的情况是无法释放新申请空间的内存的
// 一个做法是记录所有申请空间的头节点,方便对所有头节点进行delete[]
if (freeHead != nullptr)
{
delete[] freeHead;
}
}
void *malloc()
{
if (freeHead == NULL)
{
cout << "申请新空间" << endl;
FreeNode *p = new FreeNode[Num];
for (int i = 0; i < Num - 1; i++)
{
p[i].next = &p[i + 1];
}
p[Num - 1].next = NULL;
freeHead = p;
}
cout << "调用malloc" << endl;
FreeNode *ret = freeHead;
freeHead = freeHead->next;
ret->next = NULL;
return ret;
}
void free(void *ptr)
{
// 使用链表头插法实现free
FreeNode *p = (FreeNode *)ptr;
p->next = freeHead;
freeHead = p;
cout << "调用free" << endl;
}
};
Mempool<4, 2> mp;
class ActualClass
{
static int count;
int no;
public:
ActualClass()
{
no = count;
count++;
};
~ActualClass(){};
void *operator new(size_t size)
{ //具体实现类需要重载的函数
return mp.malloc();
}
void operator delete(void *p)
{ //具体实现类需要重载的函数
return mp.free(p);
}
void print()
{
cout << "object No " << no << endl;
}
};
int ActualClass::count = 0;
int main()
{
ActualClass *a = new ActualClass();
a->print();
ActualClass *b = new ActualClass();
b->print();
ActualClass *c = new ActualClass();
c->print();
delete a;
delete b;
delete c;
}
参考文献
https://www.jianshu.com/p/bbba7e72fa59