两年前一位同事和我说过,单片机不能实现动态内存管理,两天后我在keil上利用malloc()在coterx m3芯片上实现了一个链表,然后把代码给他看了,对固执的人摆事实好过讲道理。之后我觉得使用malloc()并不能满足我的需求,然后想自己实现一个heap管理。这就是这篇文章的由来,这是我今天下午突然想到的一种简单的方法,其实这很没有意义,因为我能想到的东西,别人都已经做出来了。嗯,姑且当是一个编程题的实现吧。数据结构很简单,就是先开辟一个大数组,然后将数组分割,每个块大小固定,我定义为16个字节,每个块用一个字节管理,然后记录下有几个块没有被使用。malloc的实现,输入形参和malloc一样,就是内存需求大小,申请成功返回地址,不成功返回NULL。实现思想如下,先计算的出需要几个内存块,然后检测剩余内存块是否足够,如果足够,再检测是否连续,都满足的话,将第一个内存块的管理单元赋值1,第二个赋值2,以此类推。然后将剩余内存块数量减去使用掉的数量,返回地址。free的实现,输入形参和free一样,就是malloc获得的地址,无返回。实现思想如下,先计算出地址相对heap起始地址的偏移,然后得出相应的内存管理单元,如果该内存管理单元为1,将该单元以下连续管理单元都清空,然后将剩余内存块加上相应的地址,返回。这份代码算是1.0版本,没有dubug过,不建议使用。没有debug的原因是没有想到怎么实现碎片管理的办法,我想在2.0版本上面实现,这个姑且算是一份伪代码吧。如果谁有内存碎片管理算法的一些想法的话,欢迎讨论。#include "string.h"
#define HEAP_QLY 16
struct general_buf
{
uint32_t block_qly; //剩余缓存块
uint8_t dirty[100]; //缓存空间脏标志
uint8_t buffer[HEAP_QLY*100]; //缓存空间
}Heap_Buf;
/*
* 功能:通用缓存初始化
* 输入:无
* 输入:无
* 返回:无
* 备注:
*/
void heap_buffer_init(void)
{
Heap_Buf.block_qly = sizeof(Heap_Buf.dirty);
memset(Heap_Buf.buffer,0,sizeof(Heap_Buf.buffer));
memset(Heap_Buf.dirty,0,sizeof(Heap_Buf.dirty));
}
/*
* 功能:堆内存获取函数
* 输入:无
* 输入:无
* 返回:无
* 备注:
*/
void* my_malloc(uint32_t size)
{
uint32_t size_need=size/HEAP_QLY+(size%16?1:0);/*获得块需求*/
uint32_t i,j;
uint32_t free_num=0;
uint8_t* address=NULL;
uint8_t enought_space=0;
if(size_need>Heap_Buf.block_qly)
return NULL;
for(i=0;i=size_need){
enought_space=1;
break;
}
}else
free_num=0;
}
if(enought_space){
Heap_Buf.block_qly -= free_num;
address = &Heap_Buf.buffer[(i-(free_num-1))*HEAP_QLY];
for(j=0;j=sizeof(Heap_Buf.dirty));
}
}
写于2018年3月20日夜深圳