c实现的内存池

来源:互联网 发布:苹果手机便签软件 编辑:程序博客网 时间:2024/04/27 20:13

中间用简单链表就可以,效率不错,分配时比老程的快,没有详细测试。
做全局的分配释放函数,可以像sgi stl中那样建16个全局的内存池,释放时还可以提供一个带大小的函数以提高效率。
新的block放在链表首部,对连续的new有利,对后new先delete有利。

做成环链表的好处是成功回收空间后,让blocklist指向该block,这样下次分配时就不用遍历blocklist了。删除时如果块回收之后全部空闲应释放块。分配空间时也应更新blocklist。这个先记下来。

频繁使用字符串造成内存碎片用内存池就可以解决,只是要记录其长度。
在c++中如果使用泛型的内存池(虽然看起来很有技巧),通用性不好,不能动态指定内存池,一次性分配多个对象不会调用内存池分配,不适合使用字符串,简单数据类型(必须继承),而且类都必须继承这个池。

至于alloc和free的线程安全,每个池加锁即可,这样在多线程环境下内存池的效率应该更具优越性。

SGI的内存池是全局的,因为不记录各个块(统一交给退出程序时释放),控制简单,内存利用充分,分配和释放都十分快速。但有一个不好的是,一旦程序占用了内存就不释放。

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

typedef struct hat_mempool hat_mempool;
typedef struct hat_mempool_block hat_mempool_block;
typedef struct hat_mempool_unit hat_mempool_unit;

struct hat_mempool
{
long unit_size;
long block_size;
hat_mempool_block* block_list;
};

struct hat_mempool_block
{
hat_mempool_unit* free_list;
hat_mempool_block* next;
char data[1];
};

struct hat_mempool_unit
{
hat_mempool_unit* next;
};

void hat_mempool_init(hat_mempool* pool, long unit_size, long block_size)
{
pool->unit_size = (unit_size + 3) & 0xfffffffc;/*按4字节对齐*/
pool->block_size = block_size;
pool->block_list = NULL;
}

void hat_mempool_term(hat_mempool* pool)
{
hat_mempool_block *block = pool->block_list, *tmp;
while (block)
{
tmp = block->next;
free(block);
block = tmp;
}
}

void* hat_mempool_alloc(hat_mempool* pool)
{
hat_mempool_block *block = pool->block_list, **ppblock = &pool->block_list;
hat_mempool_unit *unit;
long i;

while (block)
{
if (block->free_list)
{
unit = block->free_list;
block->free_list = unit->next;
return unit;
}
block = block->next;
}

block = malloc(pool->block_size * pool->unit_size + 8);
if (!block)
{
return NULL;
}

*ppblock = block;
unit = block->free_list = (hat_mempool_unit*)(block->data + pool->unit_size);
block->next = NULL;

for (i = 2; i < pool->block_size; ++i,unit = unit->next)
{
unit->next = (hat_mempool_unit*)((char*)unit + pool->unit_size);
}
unit->next = NULL;

return block->data;
}

void hat_mempool_free(hat_mempool *pool, void* ptr)
{
hat_mempool_block *block = pool->block_list;
hat_mempool_unit *unit;
long ptrdiff;

while (block)
{
ptrdiff = (long)((char*)ptr - block->data);
if (ptrdiff >= 0 && ptrdiff < pool->unit_size * pool->block_size)
{
if (ptrdiff % pool->unit_size)
{
return;
}
for (unit = block->free_list; unit; unit = unit->next)
{
if (unit == ptr)
{
return;
}
}

unit = block->free_list;
block->free_list = ptr;
((hat_mempool_unit*)ptr)->next = unit;
return;
}

block = block->next;
}
}

#define ALLOC_TIMES 1000000
int main()
{
clock_t pre;
long i;
hat_mempool pool;

hat_mempool_init(&pool, sizeof(long), 20);
pre = clock();
for (i = 0; i < ALLOC_TIMES; ++i)
{
hat_mempool_alloc(&pool);
}

printf("mem pool use %d clocks./n", clock() - pre);

hat_mempool_term(&pool);
scanf("%d", &i);
return 0;
}

原创粉丝点击