版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/yp18792574062/article/details/76034455
#include<iostream>
#include<malloc.h>
using namespace std;
//C++实现一个简单的内存池
class CMemPool
{
private:
//链表节点
typedef struct _Node
{
struct _Node* prev;
struct _Node* next;
}Node;
//内存池的首地址
void* m_pMemBlockAdd;
//已分配出去的内存节点
Node* m_pAllocatedMemBlock;
//未分配出去的内存节点
Node* m_pFreeMemBlock;
//内存单元个数
int m_count;
//内存单元大小(这里指总大小)
int m_BlockSize;
public:
CMemPool(int count = 50, int size = 1024);
~CMemPool();
//分配内存
void* Alloc(int size, bool useMemPool = true);
//释放内存
void Free(void* p);
};
CMemPool::CMemPool(int count, int size)
:m_pMemBlockAdd(NULL), m_pAllocatedMemBlock(NULL), m_pFreeMemBlock(NULL) //除了内存空间大小,还有加上每个节点的两个指针
,m_count(count), m_BlockSize(count*(size+sizeof(Node)))
{
m_pMemBlockAdd = ::malloc(m_BlockSize);
if (m_pMemBlockAdd != NULL)
{
//将所有节点连接起来,刚开始的时候都是空闲的
for (int i = 0; i<count; i++) //将所有内存结点链接起来
{
//每个节点的起始位置
Node *pCurUnit = (Node *)((char *)m_pMemBlockAdd + i*(size + sizeof(Node)));
//这里采用的是头插法,双向单链表,不带头结点
pCurUnit->prev = NULL;
pCurUnit->next = m_pFreeMemBlock;
if (NULL != m_pFreeMemBlock)
{
m_pFreeMemBlock->prev = pCurUnit;
}
m_pFreeMemBlock = pCurUnit;
}
}
}
CMemPool::~CMemPool()
{
::free(m_pMemBlockAdd);
}
//分配内存
void* CMemPool::Alloc(int size, bool useMemPool)
{
if (size > m_BlockSize || useMemPool == false || m_pMemBlockAdd == NULL || m_pFreeMemBlock == NULL)
{
//内存池中没有空闲的内存了,那么重新给分配内存,就不是从内存池中分配内存了
return ::malloc(size);
}
//内存池中有空闲内存
Node* r = m_pFreeMemBlock;
//先从表中取出一个内存单元,放入已分配的内存链表中,并且返回该单元的内存地址
m_pFreeMemBlock = r->next;
if (m_pFreeMemBlock == NULL)
{
m_pFreeMemBlock->prev = NULL;
}
r->next = m_pFreeMemBlock;
if (m_pAllocatedMemBlock != NULL)
{
m_pAllocatedMemBlock->prev = r;
}
m_pAllocatedMemBlock = r;
return (void *)((char *)r + sizeof(Node));
}
//释放内存
void CMemPool::Free(void* p)
{
//p在内存池分配的内存中间
if (m_pMemBlockAdd<p && p<(void *)((char *)m_pMemBlockAdd + m_BlockSize))
{
Node *pCurUnit = (Node *)((char *)p - sizeof(Node));
m_pAllocatedMemBlock = pCurUnit->next; //从已分配链表取出回收的内存单元,放入空闲链表中
if (NULL != m_pAllocatedMemBlock)
{
m_pAllocatedMemBlock->prev = NULL;
}
pCurUnit->next = m_pFreeMemBlock;
if (NULL != m_pFreeMemBlock)
{
m_pFreeMemBlock->prev = pCurUnit;
}
m_pFreeMemBlock = pCurUnit;
}
//如果不是在内存池中分配的直接销毁它
else
{
free(p);
}
}