资源消耗很小的内存池代码

来源:互联网 发布:淘宝违规产品怎么上架 编辑:程序博客网 时间:2024/05/22 20:49

#include "stdio.h"


//申请空间头结构
struct new_head{            
    unsigned
int new_size; //申请空间块总大小
    void * p_use;
    unsigned
int magic;    //合法性校验,值为(p_user+new_size)
};

//空闲空间头结构
struct free_head{
    unsigned
int free_size;   //空闲块总大小
    struct free_head * prev;  //上一个空闲块指针
    struct free_head * next;  //下一个空闲块指针
    unsigned int magic;       //合法性校验,值为 (prev+next+free_size)
};

//定义magic宏
#define NEW_MAGIC(var_addr) ((unsigned int)var_addr->p_use+var_addr->new_size)
#define FREE_MAGIC(var_addr) ((unsigned int)var_addr->prev + (unsigned int)var_addr->next + var_addr->free_size)

//错误码
#define HEAP_ERR 1  //堆检查错误
#define FREE_ERR 2  //释放指针错误
#define SIZE_ERR 3  //平台移植问题

struct free_head *global_first_pFreeHead;  //全局 地址最低的空闲块

//错误处理打印函数
void _RamDP_error(int err_code, char * file_name, unsigned int line_num)
{
    printf(
"***出现错误:%s中第%d行/r/n",file_name,line_num);
   
switch(err_code)
    {
   
case HEAP_ERR:
       
//堆检查错误
        printf("***堆检查错误,存在指针超范围使用。/r/n");
       
break;
   
case FREE_ERR:
       
//释放指针检查错误
        printf("***指针检查错误,该指针已被释放或存在指针超范围使用。/r/n");
       
break;
       
   
case SIZE_ERR:
       
//平台移植性问题
        printf("***存在平台移植性问题,可在struct free_head 或struct new_head中增加字符数组时表达式sizeof(free_head)和sizeof(new_head)+sizeof(int)大小相等。");
       
break;
   
default:
       
//
        0;
    }
   
while(1);
};

//初始化动态内存块
int free_init(void* start_add,unsigned int size)
{
   
if(sizeof(free_head)!=sizeof(new_head)+sizeof(int))
    {
        _RamDP_error(SIZE_ERR,__FILE__,__LINE__);
    }

    global_first_pFreeHead
= (struct free_head *)start_add;
    global_first_pFreeHead
->free_size = (size/sizeof(int))*sizeof(int);
    global_first_pFreeHead
->prev = global_first_pFreeHead;
    global_first_pFreeHead
->next = NULL;
    global_first_pFreeHead
->magic = FREE_MAGIC(global_first_pFreeHead);
   
return 0;
}

/************************************/
/******** 申请内存函数 **************/
/*** 使用宏 new_n() 实现调试信息 ***/
#define new_n(new_size) New_SelfTest(new_size, __FILE__, __LINE__)
void * New_SelfTest(unsigned int new_size, char * file_name, unsigned int line_num)
{
   
struct free_head * p_free = NULL;  //链表遍历指针
    struct free_head * tmp = NULL;     //暂存指针
    struct new_head * new_tmp;       //申请内存头指针

   
if(new_size == 0) return NULL;
    new_size
= (((new_size - 1) / sizeof(int) ) * sizeof(int)) + sizeof(int); //使申请字节数为sizeof(int)的倍数

   
for(p_free = global_first_pFreeHead; p_free != NULL; p_free = p_free->next)  //查找空闲块链表中符合要求的最小块
    {
       
/// for debug
        if(p_free->magic != FREE_MAGIC(p_free)) //检查空闲内存头合法性
        {
            _RamDP_error(HEAP_ERR,file_name,line_num);
           
return NULL;
        }

       
if(p_free->free_size >= (new_size + sizeof(struct new_head)))
        {
           
if(tmp == NULL || tmp->free_size > p_free->free_size)
            {
                tmp
= p_free;
            }
        }
    }

   
if(tmp != NULL)   //从该空闲块中剥离申请空间
    {   
        p_free
= (struct free_head *)(((char *)tmp) + new_size + sizeof(struct new_head));
       
if(p_free <= (struct free_head *)((char *)tmp + tmp->free_size - sizeof(struct free_head)))
        {
            p_free
->free_size = tmp->free_size - (new_size + sizeof(struct new_head));
           
if(global_first_pFreeHead == tmp)
            {
                global_first_pFreeHead
= p_free;
                p_free
->prev=p_free;
            }
           
else
            {
                p_free
->prev=tmp->prev;
            }
            p_free
->next = tmp->next;
            p_free
->magic = FREE_MAGIC(p_free);
        }
       
else
        {
           
if(global_first_pFreeHead == tmp)
            {
                global_first_pFreeHead
= tmp->next;

                tmp
->next->prev = tmp->next;
                tmp
->next->magic = FREE_MAGIC(tmp->next);
            }
           
else
            {
                tmp
->prev->next=tmp->next;
                tmp
->prev->magic=FREE_MAGIC(tmp->prev);

                tmp
->next->prev=tmp->prev;
                tmp
->next->magic=FREE_MAGIC(tmp->next);
            }
        }
    }
   
else
       
return NULL;
   
   
// 将剥离的空间初始化,并返回可用空间指针
    new_tmp = (struct new_head *)tmp;
    new_tmp
->new_size = new_size + sizeof(struct new_head);
    new_tmp
->p_use=((char *)new_tmp) + sizeof(struct new_head);
    new_tmp
->magic = NEW_MAGIC(new_tmp);
   
return new_tmp->p_use;
}

/************************************/
/******** 内存释放函数 **************/
/*** 使用宏 free_n() 实现调试信息 ***/
#define free_n(p) Free_SelfTest(p,__FILE__,__LINE__)
void Free_SelfTest(void *p,char * file_name, unsigned int line_num)
{
   
struct new_head * p_tmp;    //
    struct free_head * p_new;   //
    struct free_head * p_free;  //链表遍历指针
    unsigned int bytes_num;     //记录释放空间大小

    p_tmp
= (struct new_head *)((char *)p - sizeof(struct new_head)); //指向申请内存头
    p=NULL; //将p设为NULL,防止成为野指针。

   
if(p_tmp->magic != NEW_MAGIC(p_tmp)) //检查内存头合法性
    {
        _RamDP_error(FREE_ERR,file_name,line_num);
       
return;
    }

    bytes_num
= p_tmp->new_size;//记录释放空间大小
    p_new = (struct free_head *)p_tmp;  //将该内存块变为空闲块
    p_new->free_size = bytes_num;

   
for(p_free = global_first_pFreeHead; p_free != NULL; p_free = p_free->next) //将释放区域插入链表中
    {
       
/// for debug
        if(p_free->magic != FREE_MAGIC(p_free)) //检查空闲内存头合法性
        {
            _RamDP_error(HEAP_ERR,file_name,line_num);
           
return;
        }

       
if(p_new < p_free)                       //插在当前快链的前面
        {
           
if(global_first_pFreeHead == p_free)
            {
                global_first_pFreeHead
= p_new;
                p_new
->prev = p_new;
            }
           
else
            {
                p_new
->prev = p_free->prev;
            }
            p_new
->next = p_free;

            p_free
->prev = p_new;
            p_free
->magic = FREE_MAGIC(p_free);
           
break;
        }
       
else if(p_new < p_free->next || p_free->next == NULL)
        {
            p_new
->prev = p_free;
            p_new
->next = p_free->next;

            p_free
->next->prev = p_new;
            p_free
->next->magic = FREE_MAGIC(p_free);
           
            p_free
->next = p_new;
            p_free
->magic = FREE_MAGIC(p_free);
           
break;
        }
    }
    p_new
->magic = FREE_MAGIC(p_new);

   
if(p_new == (struct free_head *)((char *)p_new->prev + p_new->prev->free_size))  //判断前向连续性
    {
        p_new
->prev->next = p_new->next;
        p_new
->prev->free_size += p_new->free_size;
        p_new
= p_new->prev;
        p_new
->magic = FREE_MAGIC(p_new);
    }

   
if(p_new == (struct free_head *)((char *)p_new->next - p_new->free_size))  //判断后向连续性
    {
        p_new
->free_size += p_new->next->free_size;
        p_new
->next = p_new->next->next;
        p_new
->magic = FREE_MAGIC(p_new);
    }

}

/************************/
/******* 测试代码 *******/
/************************/
#include
"stdio.h"
unsigned
int free_tmp[1024*1024*2/4]={0};   //测试使用,为堆开辟空间。

int main(int argc, _TCHAR* argv[])
{
    unsigned
int i=0;
    printf(
" int类型字节数为:%d /r/n 无符号整形最大值为:%u /r/n 打印文件名: %s/r/n 行号: %d/r/n",sizeof(int),/
        i
-1,__FILE__,__LINE__);
    free_init(free_tmp,
1024*1024*2);
   
   
int * p0=(int *)new_n(sizeof(int));
   
*p0=0x12345678;


   
int *p1=(int *)new_n(sizeof(int));
   
*p1=0x77777777;
   
//free_n(p0);

    free_n(p0);
    p0
=(int *)new_n(sizeof(int));
   
*p0=0x11223344;

   
int *p2=(int *)new_n(sizeof(int)*1);
    p2[
0]=0x12341234;
   
//p2[1]=0x66668888;

    free_n(p1);
    p1
=(int *)new_n(sizeof(int));
   
*p1=0x11223344;

   
int * p3=(int *)new_n(sizeof(int)*1);
    p3[
0]=0x11111111;
   
//p3[1]=0x22222222;
   
//p3[2]=0x33333333;

    free_n(p0);
   
//free_n(p0);
    free_n(p2);
    free_n(p3);
    free_n(p1);
   
return 0;
}

原创粉丝点击