三、分配内存
首先看一个核心代码如下
[csharp] view plain copy
print?
- /**************************************************************************************
- * 名 称: mem_malloc
- * 功 能: 内存分配(内部调用)
- * 参 数:
- * memx:所属内存块
- * size:要分配的内存大小(字节)
- * 返 回 值: 0XFFFFFFFF,代表错误;其他,内存偏移地址
- **************************************************************************************/
- u32 mem_malloc(u8 memx,u32 size)
- {
- signed long offset=0;
- u16 nmemb; //需要的内存块数
- u16 cmemb=0; //连续空内存块数
- u32 i;
- if(!mallco_dev.memrdy[memx])
- mallco_dev.init(memx); //未初始化,先执行初始化
- if(size==0)return 0XFFFFFFFF; //不需要分配
-
-
- nmemb=size/memblksize[memx]; //获取需要分配的连续内存块数
- if(size%memblksize[memx])nmemb++;
- for(offset=memtblsize[memx]-1;offset>=0;offset--) //搜索整个内存控制区
- {
- if(!mallco_dev.memmap[memx][offset])
- cmemb++; //连续空内存块数增加
- else
- cmemb=0; //连续内存块清零
- if(cmemb==nmemb) //找到了连续nmemb个空内存块
- {
- for(i=0;i<nmemb;i++) //标注内存块非空
- {
- mallco_dev.memmap[memx][offset+i]=nmemb;
- }
- return (offset*memblksize[memx]); //返回偏移地址
- }
- }
- return 0XFFFFFFFF; //未找到符合分配条件的内存块
- }
1、首先进行的是一个初始化,初始化的作用上面已经提及,再次不赘述,这里我们假设一块内存为40个block(一个block为32字节,因为内存太小)那么接下来可以看到是通过我们传入的参数计算出了总的内存块数,并且如果不整除的话,还会多分配一个内存块。nmemb = 64。内存管理表内容用于检测该块是否被占用。注意这里的内存块一定是连续的, 内存管理表的项值代表的意义为:当该项值为0的时候,代表对应的内存块未被占用,当该项值非零的时候,代表该项对应的内存块已经被占用,其数值则代表被连续占用的内存块数。比如某项值为10,那么说明包括本项对应的内存块在内,总共分配了10个内存块给外部的某个指针。
之后就是标志代码了,注释很详细,接下来看看这个返回偏移地址的代码:offset*memblksize[memx],这个偏移值就是memblksize【0】 = 0x20*offset 2、好的,接下来就是将偏移值转化为所谓的外部指针了。
[csharp] view plain copy
print?
- else return (void*)((u32)mallco_dev.membase[memx]+offset);
这行代码,返回一个void 类型的首地址就是mallco_dev.membase[0],这样我们就得到了一个地址了。
3、然后就是
[csharp] view plain copy
print?
- p=mymalloc(sramx,2048); //申请2K字节
- if(p!=NULL)sprintf((char*)p,"This is xiaobing's Memory Malloc Test!!");//向p写入一些内容
- printf("%s",p); //显示P的内容
这就是把这个地址传给指针p,那么我们接着就可以给指针p赋值内容了,这回爽到了吧? 打印指针内容。 4、很重要的一步 myfree(sramx,p);//释放内存,否则资源难以回收
记得要释放内存呀,看代码函数
[csharp] view plain copy
print?
- /**************************************************************************************
- * 名 称: mem_free
- * 功 能: 释放内存(内部调用)
- * 参 数:
- * memx:所属内存块
- * offset:内存地址偏移
- * 返 回 值: 0,释放成功;1,释放失败;
- **************************************************************************************/
- u8 mem_free(u8 memx,u32 offset)
- {
- int i;
- if(!mallco_dev.memrdy[memx]) //未初始化,先执行初始化
- {
- mallco_dev.init(memx);
- return 1; //未初始化
- }
- if(offset<memsize[memx]) //偏移在内存池内.
- {
- int index=offset/memblksize[memx]; //偏移所在内存块号码
- int nmemb=mallco_dev.memmap[memx][index]; //内存块数量
- for(i=0;i<nmemb;i++) //内存块清零
- {
- mallco_dev.memmap[memx][index+i]=0;
- }
- return 0;
- }else return 2; //偏移超区了.
- }
就是将内存块清零,与之前的那行代码对应就是
[csharp] view plain copy
print?
- mallco_dev.memmap[memx][offset+i]=nmemb;
标注非空了,那么也就是说,我们占用了的那些内存块就会标记为nmenb,否则就是0。
当我们释放完内存后,记得加上这个 P = NULL. 只是为了防止产生野指针,谁能保证,每次运行程序的时候,给变量分配地址的时候,不会使用到这个地址呢??所以这是个好习惯!
|