天天看点

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

#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;

}

#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;

}

#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;

}