一种轻巧的“内存动态分配管理机制”-凯发app官方网站

凯发app官方网站-凯发k8官网下载客户端中心 | | 凯发app官方网站-凯发k8官网下载客户端中心
  • 博客访问: 491250
  • 博文数量: 174
  • 博客积分: 130
  • 博客等级: 入伍新兵
  • 技术积分: 587
  • 用 户 组: 普通用户
  • 注册时间: 2011-01-12 19:39
文章分类

全部博文(174)

文章存档

2018年(2)

2016年(10)

2015年(6)

2014年(31)

2013年(92)

2012年(33)

我的朋友
相关博文
  • ·
  • ·
  • ·
  • ·
  • ·
  • ·
  • ·
  • ·
  • ·
  • ·

分类: c/c

2016-12-01 13:53:45

原文地址: 作者:

一种轻巧的“内存动态分配管理机制”

文章来源:http://gliethttp.cublog.cn

(1)首先计算需要管理的内存区域一共有多少个sizeof(header)内存动态管理组dmg,放入header->s.size中
(2)malloc分配的内存从最后dmg组开始
(3)本次分配的内存管理单元header和数据一起分配,并位于此次分配出去的内存管理组dmg的第一组,数据紧跟其后
(4)一次分配最小数据空间sizeof(header)=8字节,也就是说如果malloc(3),那实际分配的数据空间是8字节,容易有碎片
(5)动态增长dmg使用morecore(u32 nu);可以从当前os中再申请nu个dmg
(6)刚刚使用free释放的内存空间,经过边界合并后,将其加入free链表,同时更改freep指向p
(7)有一点需要注意:因为free链表空闲内存是从小地址->大地址顺序链接的,所以p >= p->s.ptr,说明p位于
   内存最大地址处[最末尾],但此时p->s.ptr可能不是&base.
//------------------------------------------------
//1.空闲链表结构体定义如下
typedef u32 align;
union header
{
    struct
    {
        union header *ptr;
        u32 size;
    }s;
    align x;//该x仅用于编译器对header结构体的4字节对齐
};
typedef union header header;
//------------------------------------------------
//2.malloc()内存动态分配管理函数
#include "malloc.h"
char * __heap_start = (char *)(0x02000000 0x5800);
char * __heap_end = (char *)(0x0203ffff);
static header base;       //未必是空闲链表开始,只是一个普通header元素,&base地址值未必最小
static header *freep=null;//未初始化
int is_run = 0;
void *malloc(u32 nbytes)
{header *p, *prevp;
 u32 nunits;
    //计算管理nbytes数据需要多少个dmg[gliethttp]
    nunits = (nbytessizeof(header)-1)/sizeof(header) 1;
    
    prevp = freep;
    if(prevp == null)
    {//第一次运行,初始化之
        base.s.ptr = freep = prevp = &base;//base.s.ptr指向其自身&base
        base.s.size=0;//无大小,base.s.size=0;
    }
    for(p = prevp->s.ptr;;prevp = p,p = p->s.ptr)
    {
        if(p->s.size >= nunits)//足够大
        {
            if(p->s.size == nunits)//大小刚好
            {
                prevp->s.ptr = p->s.ptr;
            }else
                {//如果p->s.size大了,那么切割,从尾部分配出去nunits个dmg
                    p->s.size -= nunits;
                    p = p->s.size;
//(char*)p p->s.size*sizeof(header),p指向管理nbytes个字节的dmg第一组
                    p->s.size = nunits;
                }
            freep = prevp;
            return (void *)(p1);//返回紧跟dmg管理第一组后的数据区指针
        }
        if(p == freep)
        {//从freep开始搜索了一圈,出现回环
            p = morecore(nunits);//尝试从操作系统中再获取一些内存,不同os有不同的方式
            if(p==null)return null;//实在是没有可用内存了,那么只能false
        }
    }
}
//------------------------------------------------
//3.free()内存释放函数
void free(void *ap)
{header *bp, *p;
    //(header *)ap-1,读取控制当前ap内存的控制单元dmg第一组
    bp = (header *)ap-1;
    for(p=freep;!(bp > p && bp < p->s.ptr); p=p->s.ptr)
    {
//p >= p->s.ptr表明数据回环了,此时p为管理的内存最大地址值[最末尾],p->s.ptr可能不是&base

//bp可能比最大的p大,也可能比最小的p->s.ptr小,但都无关紧要,都能形成由小->大的顺序链表
        if(p >= p->s.ptr && (bp > p || bp < p->s.ptr))break;
    }
    if(bp bp->s.size == p->s.ptr)
    {
        //和bp后边的p->s.ptr合并
        bp->s.size = p->s.ptr->s.size;
        bp->s.ptr = p->s.ptr->s.ptr;
    }else
        {
            bp->s.ptr = p->s.ptr;//将bp插到p->s.ptr前面
        }
    if(p p->s.size == bp)
    {
        //和bp前边的p合并
        p->s.size = bp->s.size;
        p->s.ptr = bp->s.ptr;    
    }else
        {
            p->s.ptr = bp;//将bp插到p后面
        }
    freep = p;
}
//------------------------------------------------
//4.morecore()从当前os中获取更多内存的函数
header *morecore(u32 nu)
{char *cp;
 header *up;
    if(is_run)return null;
    is_run = 1;
    //第一次调用
    nu = (__heap_end - __heap_start)/sizeof(header) - 1;
    cp = (char *)__heap_start;
    up = (header *)cp;
    up->s.size = nu;//空闲内存
    free((void *)(up1));//释放紧接dmg第一组的内存空间
    return freep;
}
//上面函数的原型是
#define nalloc 1024 //一次至少向os申请nalloc个dmg单元
static header *morecore(unsigned nu)
{char *cp, *sbrk(int);
 header *up;
    if (nu < nalloc)
     nu = nalloc;//至少向os申请nalloc个dmg单元
    cp = sbrk(nu * sizeof(header));
//通过unix的sbrk系统调用,在进程的末尾增加内存空间,能保证&base地址值最小
    if (cp == (char *) -1)
     return null;
    up = (header *) cp;
    up->s.size = nu;
    free((void *)(up1));//将新增的空间添加到free空闲队列
    return freep;
}
//------------------------------------------------
//5.init_malloc()初始化windows下使用的__heap_start和__heap_end
void init_malloc()
{
    //calloc分配内存,同时清0
    __heap_start = (char *)calloc(0x400000, sizeof(char));
    __heap_end = (char *)(__heap_start 0x400000);
}

阅读(1618) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~
")); function link(t){ var href= $(t).attr('href'); href ="?url=" encodeuricomponent(location.href); $(t).attr('href',href); //setcookie("returnouturl", location.href, 60, "/"); }
网站地图