嵌入式C语言入门——内存管理

程序结构

  • 栈区
  • 堆区
  • 数据区
    • 未初始化的全局,静态数据
    • 初始化的全局,静态数据
  • 代码区

内存分配方式

  • 静态分配
    • 代码区
    • 数据区
  • 动态分配
    • 栈区:系统分配
    • 堆区:程序员调用malloc系列函数分配

内存管理函数

malloc

void * malloc(size_t size);

malloc(配置内存空间)
表头文件:#include <stdlib.h>
函数参数:无符号整型数据
函数说明:malloc()在动态存储区分配size字节的连续空间
返回值:成功返回指向空间起始地址的指针,失败返回NULL

realloc

void *realloc(void *ptr, size_t size)

relloc(变更已经配置的内存空间)
当需要扩大一块内存空间时,realloc()试图直接从堆上当前内存段后面的字节中获得更多的内存空间.

  • 如果能够满足,则返回原指针;
  • 如果当前内存段后面的空闲字节不够,那么就使用堆上第一个能够满足这一要求的内存块,将目前的数据复制到新的位置,而将原来的数据块释放掉。

参数ptr为先前由malloc、calloc和realloc所返回的内存指针,而参数size为新配置的内存大小。

calloc

void *calloc(size_t nmemb, size_t size)

calloc是malloc函数的简单包装,它的主要优点是把动态分配的内存进行初始化,全部清零。其操作及语法类似malloc()函数。

memset

void *memset(void *s, int c, size_t n)

将s中当前位置后面的n个字节 用 c 替换并返回 s

free

void free(void *ptr);

void free(void *ptr);释放原先申请的内存空间。

堆和栈的区别

管理方式不同

  • 栈编译器自动管理
  • 堆空间申请释放由程序员控制,容易产生内存泄露

空间大小不同

  • 栈向低地址拓展,是一块连续的内存空间,栈顶的地址和栈的最大容量是系统预先设定好的
  • 堆是向高地址拓展,是不连续的内存区域

是否产生碎片

堆来讲,频繁的malloc/free(new/delete)势必会造成内存空间的不连续,从而造成大量的碎片,使程序效率降低

增长方向不同

  • 堆的增长方向是向上的,即向着内存地址增加的方向
  • 栈的增长方向是向下的,即向着内存地址减小的方向

分配方式不同

  • 栈的分配和释放是由编译器完成的,栈的动态分配由alloca()函数完成
  • 堆程序malloc()动态审定分配,由free()函数释放

分配效率不同

堆的效率比栈要低得多。

猜你喜欢

转载自blog.csdn.net/qq_35599308/article/details/84666731