内存管理 - 动态开辟内存

时间:2010-04-30 11:52:17  来源:第二电脑网  作者:第二电脑网

  第二电脑网导读:的51单片机开发板玩(用的Keil),突然萌发做个贪食蛇的想法,经过考虑我打算用链表来做(当然,结果证明用链表做很不值得)可在快完工的时候我傻眼啦,蛇在吃了食物后整个屏幕都花啦(用的LCD12864的液晶屏)。本来蛇每吃一个食物其实就是动态再开辟一段蛇身。这样看来显然是动态开辟内存失败,导致绘制蛇身函数在逐个查找链表的每个节点的时候有一环被破坏没有连接到下一环。  再...
  正文:

若要转贴或使用本文章介绍的技术,请在你发布的文章或作品中注明出处。


  关于内存管理,以前我在PC机上研究系统内核时接触过。那要求在把CPU设置为32位后统一给内存做影射,而我们今天要讨论的内存管理比那是要简单多了。
  前两天拿朋友的51单片机开发板玩(用的Keil),突然萌发做个贪食蛇的想法,经过考虑我打算用链表来做(当然,结果证明用链表做很不值得)可在快完工的时候我傻眼啦,蛇在吃了食物后整个屏幕都花啦(用的LCD12864的液晶屏)。本来蛇每吃一个食物其实就是动态再开辟一段蛇身。这样看来显然是动态开辟内存失败,导致绘制蛇身函数在逐个查找链表的每个节点的时候有一环被破坏没有连接到下一环。
  再追查下去,应该就是 malloc() 函数没有发挥作用,可是很纳闷 Keil 编译器并没有报告错误。现在问题找到了,可要解决这个问题那就必须自己能构造一个 malloc() 函数。后来我查看了 malloc() 函数,具体实现如下:
  
  struct __mem__
  {
     struct __mem__ _MALLOC_MEM_ *next;    /* single-linked list */
     unsigned int        len;               /* length of following block */
  };

 typedef struct __mem__     __memt__;
  typedef __memt__ _MALLOC_MEM_ *__memp__;
  #define  HLEN  (sizeof(__memt__))
  extern __memt__ _MALLOC_MEM_ __mem_avail__ [];
  #define AVAIL  (__mem_avail__[0])
  #define MIN_BLOCK  (HLEN * 4)

 void _MALLOC_MEM_ *malloc (unsigned int size)
  {
    __memp__ q;       /* ptr to free block */
    __memp__ p;       /* q->next */
    unsigned int k;      /* space remaining in the allocated block */

 q = &AVAIL;
    while (1)
    {
      if ((p = q->next) == NULL)
      {
        return (NULL);    /* FAILURE */
      }
      if (p->len >= size)
        break;
      q = p;
    }
    k = p->len - size;    /* calc. remaining bytes in block */
    if (k < MIN_BLOCK)    /* rem. bytes too small for new block */
    {
      q->next = p->next;
      return (&p[1]);    /* SUCCESS */
    }
    k -= HLEN;
    p->len = k;
    q = (__memp__ ) (((char _MALLOC_MEM_ *) (&p [1])) + k);
    q->len = size;

return (&q[1]);      /* SUCCESS */
  }

在这我们可以看到其实他就是利用一个链表在内存中去搜索一段连续的空闲内存,并把首地址传回。可为什么他在我使用的51单片机开发板上没有发挥作用呢?经过分析,我恍然大悟。大家试想一下如果让你去分配一段内存,那么我们就必须有个纪录哪些内存在使用哪些内存空闲的机制。拿TC或VC在PC机上实验一下使用 malloc() 函数看看?它作用发挥良好,看来这个机制是由OS来完成的,而在我们那51单片机的裸机上有个毛的OS啊,也难怪 malloc() 函数不能成功的分配内存。现在找到问题的本质,那我们就来自己构造 malloc() 函数。


  建立自己的数据类型:
  文件名:MY_Type.h
  内容:
  /* 自定义类型,方便书写与在不同平台进行移植 */
  typedef char      INT8;
  typedef int        INT16;
  long             INT32;
  /*typedef float     F32;
  typedef double     F64;*/

 typedef unsigned char   UINT8;
  typedef unsigned int     UINT16;
  typedef unsigned long   UINT32;
  /*typedef unsigned float  UF32;
  typedef unsigned double  UF64;*/


  总体具体分析:
  为了能有效果的对内存进行管理,我们必须保证内存时时刻刻都能被指定并被纪录是否空闲,那么最好的做法就是先开辟好一定空间再统一管理。当然这段内存空间也必须是全局的。然后我们必须建立一个纪录列表,纪录下内存的使用状态,以便管理。


  建立管理机制:
  我们可以构造一个结构,将纪录列表和实际使用内存绑定起来。具体代码如下:

 #define  MEM_COUNT  40      /* 实际使用内存40个字节           */
  #define  MEM_LIST  MEM_COUNT >> 3    /* 管理列表 40/8 = 5个字节          */

 typedef struct
  {
    UINT8  list[MEM_LIST];        /* 管理列表共40位与实际使用内存一一对应,1表示使用中,0表示空闲  */

内存管理 - 动态开辟内存》由第二电脑网原创提供,转载请注明:http://www.002pc.com/master/College/Language/VC/2010-04-30/13826.html


关键字:

关于《内存管理 - 动态开辟内存》文章的评论

站内搜索: 高级搜索

热门搜索: Windows style 系统 tr IP QQ CPU 安装 function 注册 if td