C语言实现简单内存池

内存池的使用时很有必要的,因为他可以尽很大可能避免我们的内存碎片化,对于我们开辟小块内存的时候,他的作用尤为明显。我也实现了一个内存池,本来想和杨老师的一样高大上,但是他的代码,我实在是看不懂了,心有余而力不足。只能自己赵一份简单的实现,大体原理差不多。

原理是:我们先开辟一块内存,例如1024K,然后将这1024K管理起来,用户需要开辟内存时,判断他需要多大,如果大于128K那么我们直接调用系统的malloc函数进行开辟,如果他需要小块的内存,由我们给他进行分配。之后当我们回收内存的时候,组织一个数组,将内存挂载到我们的数组上,下次就可以直接从数组中取内存分配给他。

注意:初始化的时候,需要初始化数组中每个指针的指向,还有初始化我们的内存。每次用户申请的内存并不是完全按照他的要求,例如,我的程序是从8K开始,没8K进行管理,当用户需要10K时,实际分配给他的是16K,这也是为了方便我们的管理。其次,每次需要在分配的内存的第一个字节出填入该内存的大小,以便于我们后边插入到指针数组中。代码如下:

#pragma once
#include 
#include 

#define SMALL 8
#define BIG 128
#define SIZE BIG/SMALL

void *My_Alloc_chunk(int size,char tag);

static int Next_size = 0;
struct chunk
{
	char *freesp;
	struct chunk *next;
};
static struct chunk *chunk_head = NULL;
struct slot
{
	struct slot *next;
};
static struct slot *slots[SIZE];
void My_Mempoll_init()
{
	for(int i = 0; i < SIZE; ++i)
	{
		slots[i] = NULL;
	}
	if(chunk_head == NULL)
	{
		chunk_head = (struct chunk *)malloc(1024);
		chunk_head->freesp = (char *)chunk_head + sizeof(struct chunk);
		chunk_head->next = NULL;
		Next_size = 1024 - sizeof(struct chunk);
	}
}
void *My_Alloc(int size)
{
	void *ret = NULL;
	int i;
	for(i = 0; i < SIZE; ++i)
	{
		if(size <= (i + 1) * 8)
			break;
	}
	if(i == SIZE)
	{
		char *tmp = (char *)malloc(size + 1);
		tmp[0] = SIZE;
		ret = tmp + 1;
		printf("alloc from malloc\n");
	}
	else
	{
		ret = My_Alloc_chunk(size,i);
	}
	return ret;
}
void *My_Alloc_chunk(int size,char tag)
{
	void *ret = NULL;
	if(slots[tag] == NULL)
	{
		if(size + 1 >= Next_size)
		{
			chunk_head->freesp[0] = tag;
			ret = chunk_head->freesp + 1;
			struct chunk *ctmp;
			ctmp = (struct chunk*)malloc(1024);
			ctmp->freesp = (char *)ctmp + sizeof(struct chunk);
			ctmp->next = chunk_head;
			chunk_head = ctmp;
			printf("alloc from slot and malloc a new\n");
		}
		else
		{
			chunk_head->freesp[0] = tag;
			ret = chunk_head->freesp + 1;
			chunk_head->freesp += (size + 1);
			Next_size -= (size + 1);
			printf("alloc from list\n");
		}
	}
	else
	{
		ret = slots[tag];
		slots[tag] = slots[tag]->next;
		printf("alloc from slot\n");
	}
	return ret;
}
void My_Free(void *ptr)
{
	char *tmp = (char *)ptr - 1;
	int tag = tmp[0];
	if(tag == SIZE)
	{
		printf("use free\n");
		free(tmp);
	}
	else
	{
		printf("free ptr to %d\n",tag);
		((struct slot *)ptr)->next = slots[tag];
		slots[tag] = (struct slot*)ptr;
	}
}
void My_Free_poll()
{
	struct chunk *tmp;
	while(chunk_head != NULL)
	{
		tmp = chunk_head->next;
		free(chunk_head);
		chunk_head = tmp;
	}
	printf("chunk slots free \n");
}
测试代码:

#include 
#include "alloc.h"


int main()
{
	My_Mempoll_init();
	char *a,*b,*c,*d,*e,*f;
	a = (char *)My_Alloc(128);
	b = (char *)My_Alloc(882);
	c = (char *)My_Alloc(10);
	d = (char *)My_Alloc(6);
	e = (char *)My_Alloc(128);
	f = (char *)My_Alloc(1034);
	My_Free(a);
	My_Free(e);
	e = (char *)My_Alloc(128);
	My_Free(e);
	My_Free_poll();
}


你可能感兴趣的:(随笔,源码剖析)