EDN China > 技术文章 > 嵌入式系统 > 开发工具 > 正文
? 2016博客大赛-不限主题,寻找电子导师,大奖升级??

Keil C动态内存管理机制分析及改进

来源:单片机及嵌入式系统应用/作者:重庆电力高等专科学校 丁明亮 熊真春?? 2007年07月04日 ?? 收藏0

  3 malloc函数分析

  malloc函数的原形是void *malloc(unsigned intsize),size参数为需动态申请的内存块的字节数。

  malloc函数的算法是查找AVAIL链表中各结点next指针所指向的空闲内存块。如果某块的空闲字节数≥size参数,则停止查找,并从该块进行内存分配,返回一个指向所分配内存块的指针给应用程序。如果没有找到符合要求的空闲内存块,则返回空指针给应用程序。

  需要注意的是,AVAIL链表中除首结点AVAIL外,其余各节点位于堆中各空闲内存块开始处的一个struct__mem__结构中,其len域为该空闲块总字节数减去sizeof(stiuct__mem)后的值,即该块实际空闲的字节数;next域指向堆中下一空闲内存块。

  设链表节点p指向所找到的空闲内存块,如果在p空闲块分配size个字节后,剩余的字节数不多,则将p块从AVAIL链表中删除,然后返回一个指向p块偏移sizeof(struct__mem)处的指针。如果在p空闲块分配size个字节后,该块仍剩余较多的字节数,则需对该块进行分割,将多出的这一部分保留在AVAIL链表中。(以下部分有省略,全文请见本刊网站——编者注)

  4 free函数分析及改进

  free函数的原形是void free(void xdata *memp),参数memp指向所要释放的内存块。

  在AVAIL链表中,各结点是按其所指空闲内存块开始

地址的大小按升序排列的。free函数的算法是在AVAIL链表中查一个节点p(其前驱为q),当p节点所指空问内存块的地址大于参数memp所指内存块的起始地址时,则将memp块插入到该节点之前,如没有找到这样的节点,则memp块插到链尾。在插入memp块时,还将检查在memp块的前后是否存在地址相邻的空闲内存块,如果有,则将memp块与相邻块合并。(free库函数的部分源代码见本刊网站——编者注)

  值得探讨的是最后一段将memp块与前一块(q块)合并的这部分代码。如果在执行此部分代码之前,q指向首结点AVAIL,而此时欲将q块与memp块合并,显然是不合理的。实际上,此时应当将q的next指针的值设为memp块的开始地址p0。由于KeilC7.5A中,free库函数的源程序中没有考虑这种特殊情况,因此可能会引发严重后果。

  由源代码分析可知,q指向首结点AVAIL,而此时如果满足。memp块与q块合并的判定条件,执行q>1en+=p0一>Len+HL,EN和q一>next=pO一>next后,不但不能回收内存,反而导致memp块丢失;同时,AVAIL的len域的值也不正确。如果此时pO一>next又为NULL,则会导致整个堆内存的丢失。

  笔者特在Keil C7.5 A版中设计了一个示例(见本刊网站),用于引发该错误。要防止这种错误,只需将if((((char_MALLOC_MEM_*)q)+q一>len+HLEN)==pO)判定语句改为if((q!=&AVAIL)&&(((char_MALLOC_MEM_*)q)+q一>len+HLEN)==p0)即可。有兴趣的可通过电子邮件与笔者联系(cqdoml@sina.com)。

  编者注:本文为期刊缩略版,全文见网站www.mesnet.com.cn。


上一页12下一页
?? ?? ??


打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮

1.扫描左侧二维码
2.点击右上角的分享按钮
3.选择分享给朋友
?? ??

Keil C? 动态内存管理? 嵌入式系统编程工具?

相关文章

我来评论
美国的游客
美国的游客 ??? (您将以游客身份发表,请登录 | 注册)
?
有问题请反馈