(Memory Pool)是一种内存分配方式,又被称为固定大小区块规划(fixed-size-blocks allocation)。通常我们习惯直接使用new、malloc等API申请分配内存,这样做的缺点在于:由于所申请内存块的大小不定,当频繁使用时会造成大量的内存碎片并进而降低性能。
内存池则是在真正使用内存之前,先申请分配一定数量的、大小相等(一般情况下)的内存块留作备用。当有新的内存需求时,就从内存池中分出一部分内存块,若内存块不够再继续申请新的内存。这样做的一个显著优点是,使得内存分配效率得到提升。
简单用代码实现了一下内存池如下:
#include <string>
#include <iostream>
#include <memory>
#include <cassert>
#include <vector>
using namespace std;
const int CAP_NUM = 16;
class Object
{
public:
string str_object;
static shared_ptr<Object> getObj();//静态类型成员,不用实例化也可以调用
protected:
Object(){}
};
struct Position:Object
{
bool used;
Position* next;
} buffer[CAP_NUM];
Position* unused ;
Object* createObj()
{
//TODO
int j=0;
int i = 0;
Position *unused_copy = unused;
if(unused!=NULL) //检测还有咩有空内存
{
for ( i = 0; i <CAP_NUM ; i++)
{
if(buffer[i].used==false)
{
buffer[i].used = true;//将空内存置1后面返回给调用的
j = i;
break;
}
}
if(i==15)
{
i = -1;
}
for ( i = i+1; i < CAP_NUM ; i++)//检查后面还有没有空内存
{
if(buffer[i].used==false)
{
unused = &buffer[i];//将空内存赋给unused
break;
}
}
if(i==CAP_NUM)
{
unused = NULL;
return unused_copy;
}
return unused_copy;
}
else
{
return nullptr;//如果没有空内存,返回空指针
}
}
bool destroyObj(Object* obj)
{
//TODO
int i = 0;
for ( i = 0; i < CAP_NUM; i++)//查询送进来的指针是否为内存池的指针
{
if(obj==&buffer[i])
{
break;
}
}
if(i==CAP_NUM)
{
return false;
}
static_cast<Position *>(obj)->used=false;
unused = static_cast<Position *>(obj);
obj->str_object = "";
return false;
}
shared_ptr<Object> Object::getObj()
{
shared_ptr<Object>obj(createObj(), destroyObj);
return obj;
}
void bufferInit()
{
unused = &buffer[0];
for (int i = 0; i < CAP_NUM-1; i++)
{
buffer[i].used = false;
if (i!=CAP_NUM-1)
{
buffer[i].next = &buffer[i + 1];
}
}
buffer[CAP_NUM - 1].next = NULL;
}
void assert_obj(Object* obj)
{
auto destroy_result = destroyObj(obj);
assert(destroy_result == false);
}
int main()
{
bufferInit();
{//检测buffer[1]是不是能够销毁
Object* obj = buffer - sizeof(Position);
assert_obj(obj);
}
{//检测强制转换过来的指针能不能销毁
int getAddr;
Object* obj = reinterpret_cast<Object*>(&getAddr);
assert_obj(obj);
}
{//检测空指针能不能销毁
Object* obj = nullptr;
assert_obj(obj);
}
{//检测越界指针能不能销毁
Object* obj = buffer + CAP_NUM + 1;
assert_obj(obj);
}
{//检测新建的一个内存池中的空内存,能不能销毁
Object* obj = createObj();
destroyObj(obj);
assert_obj(obj);
}
for (int i = 0; i < 16; i++)
{
cout << buffer[i].used << endl;
}
{
vector<shared_ptr<Object>> vec_obj;
for (int i = 0; i < CAP_NUM; i++)
{
auto p = Object::getObj();
if (p != nullptr)
{
p->str_object = "" + to_string(i);
cout << p->str_object << endl;
}
vec_obj.push_back(p);
}
// for (int i = 0; i < 16; i++)
// {
// cout << buffer[i].str_object << endl;
// cout << "x" << endl;
// }
auto p_blank = Object::getObj();
assert(p_blank == nullptr);
}
cout << "all tests done!" << endl;
return 0;
}