1、使用内存池的原因
①c/c++的内存分配(malloc或new)可能会花费时间比较多
②随着时间的流逝, 会形成大量的内存碎片
2、代码:
#pragma once
#include <iostream>
#include <assert.h>
#include <typeinfo>
#define GrowValue 16
struct SingleLinkNode
{
SingleLinkNode *next;
void *check;
};
static size_t node_size = sizeof(SingleLinkNode);
static void InsertNode(SingleLinkNode *head, SingleLinkNode *node)
{
assert(head);
node->next = head->next;
head->next = node;
}
static SingleLinkNode *PopNode(SingleLinkNode *head)
{
assert(head->next);
SingleLinkNode *p = head->next;
head->next = p->next;
p->next = nullptr;
return p;
}
template <typename T>
class CObjPool
{
public:
CObjPool(size_t l = 0)
{
head_.next = nullptr;
head_.check = nullptr;
pool_size_ = 0;
Init(l);
}
bool Init(size_t l)
{
if (head_.next != nullptr)
return false;
return Grow(l);
}
void CleanMemory(void)
{
SingleLinkNode *node = head_.next;
while (node)
{
SingleLinkNode *temp = node->next;
delete node;
--pool_size_;
node = temp;
}
head_.next = 0;
}
T *AllocObj(void)
{
if (!head_.next)
{
if (!Grow(GrowValue))
return 0;
}
SingleLinkNode *p = PopNode(&head_);
return (T *)((char *)p + node_size);
}
void FreeObj(T *t)
{
SingleLinkNode *p = (SingleLinkNode *)((char *)t - node_size);
assert(p->check == this);
InsertNode(&head_, p);
}
size_t PoolSize(void)
{
return pool_size_;
}
bool IsAllocByPool(T *t)
{
if (!t)
return;
SingleLinkNode *p = (SingleLinkNode *)((char *)t - node_size);
return p->check == this;
}
private:
bool Grow(size_t l)
{
if (!l)
return true;
for (int i = 0; i < l; ++i)
{
char *ptr = new(std::nothrow) char[node_size + sizeof(T)];
if (!ptr)
return false;
SingleLinkNode *node = (SingleLinkNode *)ptr;
InsertNode(&head_, node);
++pool_size_;
new(ptr + node_size) T;
node->check = this;
}
return true;
}
private:
SingleLinkNode head_;
size_t pool_size_;
};