首先我们知道
class Node
{
public:
int a;
char b;
};
他的内存大小是8 如果此时添加 struct Obj { Obj* next; }; 也就是把那个注释取消 会发现还是八个字节 并没有多占用内存
对象池是什么
就是提前分配好例如一千个类对象 然后在需要的时候从这一千个对象中分配对象出去
定义对象池的目的是什么
一个是防止内存碎片化 直接分配一块足够大的内存 然后里面都是连续的对象 就不会需要的时候再找地方分配了 第二个是节约cookie 因为从内存那知道 我们没吃申请一个地址 地址的开头和结尾处都有额外的cookie 这样会浪费内存 所有我们如果使用对象池 就可以节约这一块内存
代码实现
#define N 1000
struct LinkedPointer {
void* ptr;
LinkedPointer* next;
};
class Node
{
public:
struct Obj { Obj* next; };
static Obj* Header;
static LinkedPointer* linkedPtr;
static int mallocCount;
private:
int a;
char b;
static void* operator new(size_t size)
{
if (nullptr == Header)
{
if (mallocCount >= 1)
{
return ::operator new(size);
}
size_t total = size * N;
void* temp = malloc(total);
mallocCount++;
Header = (Obj*)temp;
Obj* tempitem = Header;
for (int i = 1; i < N; i++)
{
void* ptr = (char*)tempitem + size;
tempitem->next = (Obj*)ptr;
tempitem = tempitem->next;
}
tempitem->next = nullptr;
LinkedPointer* linkPtr = new LinkedPointer();
linkPtr->ptr = temp;
if (linkedPtr = nullptr)
{
linkedPtr = linkPtr;
}
else
{
linkedPtr->next = linkPtr;
}
}
void* Ret = Header;
Header = Header->next;
return Ret;
}
static void operator delete(void* p, size_t size)
{
if (!IsValidPtr(p))
{
::operator delete(p);
}
if (nullptr == Header)
{
Header = (Obj*)p;
}
((Obj*)p)->next = Header;
Header = (Obj*)p;
}
static bool IsValidPtr(void* ptr)
{
if (linkedPtr->ptr >= ptr && ptr < (((char*)linkedPtr->ptr)+8000))
{
return true;
}
else
{
return false;
}
}
};
Node::Obj* Node::Header = nullptr;
LinkedPointer* Node::linkedPtr = nullptr;
int Node::mallocCount = 0;
这个上面我们就已经完成了一个初步的对象池
|