Computer ScienceCpp_backend
手写内存池(简单定长)
简单版(定长block)
设计图
代码结构
typedef struct mempool_s {
int blocksize; // 每个内存块的size
int freecount; // 剩余空的内存块数量
char *free_ptr; // 指向下一空内存块
char *mem; // 整块内存的头指针
} mempool_t;
int memp_create(mempool_t *m, int block_size) {
if (!m) return -1;
// 1. 初始化这两个简单的int
m->blocksize = block_size;
m->freecount = MEM_PAGE_SIZE / block_size;
// 2. 开整个内存池的空间,顺便初始化m->mem
m->mem = (char *)malloc(MEM_PAGE_SIZE);
if (!m->mem) { // 开失败了(剩余空闲内存不够)
return -2;
}
// 将这个空间初始化一下
memset(m->mem, 0, MEM_PAGE_SIZE);
// 3. 初始化free_ptr
m->free_ptr = m->mem;
// 依次初始化每个block里的"next->ptr"
int i = 0;
char *ptr = m->mem;
for (i = 0;i < m->freecount;i ++) {
*(char **)ptr = ptr + block_size;
ptr = ptr + block_size;
}
// 最后一个block的"next_ptr"指向NULL
*(char **)ptr = NULL;
return 0;
}
void *memp_alloc(mempool_t *m) {
// 满了
if (!m || m->freecount == 0) return NULL;
// 1. 获取当前下一个空闲块,作为返回值
void *ptr = m->free_ptr;
// 2. 更新free_ptr
m->free_ptr = *(char **)ptr;
// 3. 更新freecount
m->freecount --;
return ptr;
}
void memp_free(mempool_t *m, void *ptr) {
// 相当于 ptr->next = m->free_ptr;
// 头插法将要释放的block插到空闲block链表的头部,即空闲block链表又增加了一个
*(char **)ptr = m->free_ptr;
// 更新free_ptr这一空闲block链表头指针
m->free_ptr = (char *)ptr;
// 更新freecount
m->freecount ++;
}
void memp_destory(mempool_t *m) {
if (!m) return ;
// 直接free内存池,因为内存池是整体malloc的,而不是一个一个block malloc的
free(m->mem);
}
使用example
int main() {
mempool_t m;
memp_create(&m, 32);
void *p1 = memp_alloc(&m);
printf("memp_alloc : %p\n", p1);
void *p2 = memp_alloc(&m);
printf("memp_alloc : %p\n", p2);
void *p3 = memp_alloc(&m);
printf("memp_alloc : %p\n", p3);
memp_free(&m, p2);
}