读书人

内存池代码核心部分平台通用解决办法

发布时间: 2012-02-16 21:30:36 作者: rapoo

内存池代码,核心部分平台通用

C/C++ code
#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;} 



[解决办法]
#define align(val,align) (((val) + ((align) - 1)) & ~((align) - 1))

读书人网 >C++

热点推荐