读书人

动态内存管理代码求评价解决方案

发布时间: 2012-02-25 10:01:49 作者: rapoo

动态内存管理代码,求评价
由于嵌入式平台需求,自己写了个内存管理程序,可以动态分配和回收内存,求各位看官对该算法的评价。

C/C++ code
#include "stdio.h"unsigned int free_tmp[1024*1024*2/4]={0};//申请空间头结构struct new_head{                 unsigned int new_size; //申请空间块总大小    unsigned int magic;    //合法性校验,值为(~new_size)};//空闲空间头结构struct free_head{    unsigned int free_size;   //空闲块总大小    struct free_head * next;  //下一个空闲块指针    unsigned int magic;       //合法性校验,值为 (next+~free_size)};struct free_head *global_first_pFreeHead;  //全局 地址最低的空闲块//初始化动态内存块int free_init(void* start_add,unsigned int size){    global_first_pFreeHead = (struct free_head *)start_add;    global_first_pFreeHead->next=NULL;    global_first_pFreeHead->free_size=size;    global_first_pFreeHead->magic=(unsigned int)global_first_pFreeHead->next+~global_first_pFreeHead->free_size;    return 0;}//申请内存void * new_n(unsigned int new_size){    struct free_head * p_free=NULL;  //链表遍历指针    struct free_head * tmp=NULL;     //暂存指针    struct new_head * new_tmp;       //申请内存头指针    new_size=(((new_size-1)>>2)<<2)+4; //使申请字节数为4的倍数    for(p_free=global_first_pFreeHead;p_free!=NULL;p_free=p_free->next)  //查找空闲块链表中符合要求的最小块    {        /// for debug        if(p_free->magic!=(unsigned int)p_free->next+~p_free->free_size) //检查空闲内存头合法性        {            printf("堆栈检查错误!堆栈被破坏!\r\n");            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)   //从该空闲块中剥离申请空间    {        struct free_head * store_tmp;        p_free=tmp;        store_tmp=p_free;        p_free=(struct free_head *)(((char *)p_free)+new_size+sizeof(struct new_head));        p_free->free_size=store_tmp->free_size-(new_size+sizeof(struct new_head));        p_free->next=store_tmp->next;        p_free->magic=(unsigned int)p_free->next+~p_free->free_size;        if(store_tmp==global_first_pFreeHead)        {            global_first_pFreeHead=p_free;        }    }    else        return NULL;        // 将剥离的空间初始化,并返回可用空间指针    new_tmp=(struct new_head *)tmp;    new_tmp->new_size=new_size+sizeof(struct new_head);    new_tmp->magic=~(new_tmp->new_size);    return ((char *)new_tmp)+sizeof(struct new_head);}//释放空间void free_n(void *p){    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)); //指向申请内存头    if(p_tmp->new_size!=~p_tmp->magic) //检查内存头合法性    {        printf("wrong pointer to be free is detected! free failed!");        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;;) //将释放区域插入链表中    {        /// for debug        if(p_free->magic!=(unsigned int)p_free->next+~p_free->free_size) //检查空闲内存头合法性        {            printf("堆栈检查错误!堆栈被破坏!\r\n");            return;        }        if(p_free==global_first_pFreeHead && p_free>p_new) //插入链表首位置        {            global_first_pFreeHead=p_new;            p_new->next=p_free;            break;        }                if(p_free < p_new && p_free->next > p_new)  //插入链表中间位置        {            p_new->next=p_free->next;                        p_free->next=p_new;            p_free->magic=(unsigned int)p_free->next+~p_free->free_size;            break;        }                if(p_free->next==NULL) //插入链表末尾        {            p_free->next=p_new;            p_free->magic=(unsigned int)p_free->next+~p_free->free_size;                        p_new->next=NULL;            break;        }        else        {            p_free=p_free->next;        }    }    p_new->magic=(unsigned int)p_new->next+~p_new->free_size;    for(p_free=global_first_pFreeHead;p_free!=NULL;p_free=p_free->next) //组合连续链表    {        int flag1,flag2=NULL;        do        {            flag1=NULL;            if(p_free == (struct free_head *)((char *)p_free->next - p_free->free_size))  //判断连续性            {                p_free->free_size = p_free->free_size + p_free->next->free_size;//必须先设置大小,然后再设置链表指针                p_free->next = p_free->next->next;                                flag1=!NULL;                flag2=!NULL;            }        }while(flag1);                if(flag2)             p_free->magic=(unsigned int)p_free->next+~p_free->free_size;    }}int _tmain(int argc, _TCHAR* argv[]){    unsigned int i=0;    printf("%d  %u",sizeof(int),i-1);    free_init(free_tmp,1024*1024*2);        int * p0=(int *)new_n(sizeof(int));    *p0=0x12345678;    //free_n(p0);    int *p1=(int *)new_n(sizeof(int));    *p1=0x77777777;    //free_n(p0);    int *p2=(int *)new_n(sizeof(int)*1);    p2[0]=0x12341234;    //p2[1]=0x66668888;    int * p3=(int *)new_n(sizeof(int)*1);    p3[0]=0x11111111;    //p3[1]=0x22222222;    //p3[2]=0x33333333;    free_n(p0);    free_n(p2);    free_n(p3);    free_n(p1);    return 0;} 



[解决办法]
好长……不知道今年内我能不能看懂
[解决办法]
如果能够支持内存泄漏的检测就更好了。
[解决办法]
学习。。。。。。
[解决办法]
方便调试,是指内存泄漏的时候可以知道文件、分配行;仅仅知道存在内存泄漏是不方便分析的;

另外,printf 这样的语句不知道在你的嵌入式系统中不知道是否可以,建议写一个 log 函数,在 log 函数中调用 printf,以后方面统一换成别的输出函数;
[解决办法]
算法上有问题。
主要在回收内存时,每一次都要全部遍历,这在效率上是无法接受的。
算法要考虑到“相邻块”就可以了。
[解决办法]
unsigned int free_tmp[1024*1024*2/4]={0};


不能动态预分配?如果起不到内存池的作用,那在应用层封装一层这样的api有什么意义?

此外,可以考虑加上检测重复free,以及内存越界的检测。
[解决办法]
http://blog.csdn.net/hairetz/archive/2009/09/10/4538578.aspx

http://www.ibm.com/developerworks/cn/linux/l-cn-ppp/index6.html?ca=drs-cn

这篇可以看看哈
[解决办法]
看不太懂
纯顶

读书人网 >C++

热点推荐