内存管理
程序结构
- 栈区
- 堆区
- 数据区
- 未初始化的全局,静态数据
- 初始化的全局,静态数据
- 代码区
内存分配方式
- 静态分配
- 代码区
- 数据区
- 动态分配
- 栈区:系统分配
- 堆区:程序员调用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()函数释放
分配效率不同
堆的效率比栈要低得多。