动态内存分配
malloc
原型:extern void *malloc(unsigned int num_bytes);
用法:#include <alloc.h>
功能:分配长度为num_bytes字节的内存块
说明:如果分配成功则返回指向被分配内存的指针,否则返回空指针NULL。
当内存不再使用时,应使用free()函数将内存块释放。
举例:
// malloc.c #include <syslib.h> #include <alloc.h> main() { char *p; clrscr(); // clear screen p=(char *)malloc(100); if(p) printf("Memory Allocated at: %x",p); else printf("Not Enough Memory! "); free(p); getchar(); return 0; }
calloc
原型:extern void *calloc(int num_elems, int elem_size);
用法:#include <alloc.h>
功能:为具有num_elems个长度为elem_size元素的数组分配内存
说明:如果分配成功则返回指向被分配内存的指针,否则返回空指针NULL。
当内存不再使用时,应使用free()函数将内存块释放。
举例:
// calloc.c #include <syslib.h> #include <alloc.h> main() { char *p; clrscr(); // clear screen p=(char *)calloc(100,sizeof(char)); if(p) printf("Memory Allocated at: %x",p); else printf("Not Enough Memory! "); free(p); getchar(); return 0; }
realloc
原型:extern void *realloc(void *mem_address, unsigned int newsize);
用法:#include <alloc.h>
功能:改变mem_address所指内存区域的大小为newsize长度。
说明:如果重新分配成功则返回指向被分配内存的指针,否则返回空指针NULL。
当内存不再使用时,应使用free()函数将内存块释放。
举例:
// realloc.c #include <syslib.h> #include <alloc.h> main() { char *p; clrscr(); // clear screen p=(char *)malloc(100); if(p) printf("Memory Allocated at: %x",p); else printf("Not Enough Memory! "); getchar(); p=(char *)realloc(p,256); if(p) printf("Memory Reallocated at: %x",p); else printf("Not Enough Memory! "); free(p); getchar(); return 0; }
所有的动态内存申请,在其不再需要使用的时候,都必须free掉,否则即使是再小的内存申请,只要程序不退出,长时间的累加,内存泄漏,也会导致系统的崩溃。
动态内存分配在STM32等没有MMU的单片机中的编程
之前一直做MIPS架构芯片的编程开发,动态内存分配在项目的开发过程中是非常常见的一种使用。
最近碰到STM32调用malloc,尽然鬼使神差地在申请的动态内存使用完之后没有free掉,结果单片机运行没多久就异常了,所有这里详细地来学习下malloc等动态内存分配的使用。
malloc可以在STM32等没有MMU单元的芯片中使用
malloc( )属于标准C语言函数,所以肯定可以在运行C程序的单片机上使用,但是malloc并不适合在这样的单片机上运行。
malloc的缺点
一般来说,单片机的内存都非常的小,经常性地调用malloc等动态内存分配函数会形成内存碎片,致使可用的内存堆变小,影响系统的性能和正常运行。
为什么会形成内存碎片呢?分布式内存管理由内存池和内存管理表两部分组成。内存池被等分为N块,对应的内存管理表,大小也为N,内存管理表的每一项对应内存池的一块内存。那么这里有个问题,假如我申请65个字节,那我就得申请65%32(视处理器体系结构而定)+1个内存块,其中一个字节占用了一个内存块,这就形成了内存碎片。
另外malloc在使用过程中还得注意判断内存是否申请成功,而且内存释放后(使用free函数之后指针变量p本身保存的地址并没有改变),需要将p的值赋值为NULL(拴住野指针)。
总的来说,动态内存分配还是有很多注意点的,当然相对MIPS架构等具有内存管理单元的芯片时,没有影响,但是在没有MMU单元的单片机中,对于动态内存分配,还是尽量避免。