【IT168技术文档】
关于内存管理,以前我在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 */ }