juliusun.com
第 41/50 节 冥河C语言教程
计算机内存中有一块区域称为堆。堆可以由程序控制申请释放等操作。
堆也经常被称为动态内存。堆申请也被称为动态内存分配。堆就可以做到动态内存分配。希望其它资料上讲解动态内存分配不要陌生。
堆操作没有新的语法知识,仅仅是学习几个关于堆的函数。
堆操作函数一般封装在malloc.h中。需要引用头文件#include<malloc.h>。部分编译器是封装在stdio.h或stdlib.h中,必要时注意引用。
本节要介绍的函数有如下:
malloc : 堆空间分配函数
free : 堆空间释放
calloc : 堆空间分配、初始数据清零函数。相比malloc,此函数会把申请的内存每个字节全部设置为0,少用,不重点介绍
realloc : 修改指定堆空间大小函数
函数原型及解释如下:
void * malloc(unsigned int size)
参数size指定要申请的堆空间大小,单位为字节。返回值根据成功与否确定。分配失败返回NULL;分配成功返回被分配的堆空间指针。malloc返回void类型指针,使用时可以强制转换成自己需要的指针类型。
void free(void * p)
参数p指定要释放的堆空间地址。参数p要为堆分配函数如malloc、calloc、realloc等返回的地址。地址传递错误,运行时可能出错。函数无返回值。
void * calloc(unsigned int n,unsigned int size)
分配n块空间,每块大小是size字节。申请后的空间是连续的,总大小为n*size字节。申请成功,将这些空间每个字节都设置成0然后返回地址。申请失败返回NULL。calloc有点类似malloc(n*size),但是多一个把申请成功的空间清0的操作。此函数使用较少,本节不再详细介绍。
void * realloc(void *p,unsigned int size)
重新分配已成功申请的堆空间地址。参数p(一般为堆分配函数malloc、calloc返回的结果)为将要重新分配的堆空间地址,size为修改之后的空间大小。修改成功,返回新的堆空间地址,失败返回NULL。
注意:重新分配,realloc返回的地址可能与p相同或不同。当重新分配的空间大小大于以前时,realloc尽量在原地址扩展,扩展成功,就直接返回原地址p。扩展失败,会重新申请堆空间,并将p指向的堆空间数据复制到新空间中,释放掉原堆空间,然后返回新空间地址。重新分配失败,返回NULL。重新分配的空间小于原空间大小时,一般返回就是原空间地址。仅仅释放部分堆空间。
重新分配空间时,realloc会保留原有的数据。堆空间缩小时,保留新字节数的数据。
堆空间分配成功,不需要时请调用free函数释放系统资源,降低对系统资源的浪费。如果一直不释放申请的堆空间,程序直到退出系统才会自动收回。
举例说明,先让用户输入数字n,然后再输入n个整数。计算n个整数的值并输出算式。
分析,由于是用户动态输入n,所以用数组不合适,数组定义时必须是常量。数组元素定义少了,可能不无承受用户输入的数字个数,分配太多,会造成浪费。用堆合适,用户输入多少,分配相应的空间大小即可。例:
根据输入情况,效果图不同:
修改下上面的题目,再拿realloc举个例子。假设用户不必提前输入数字,而是以输入0算作结尾。
例子解题思路是申请堆,输入数字放入堆。数字为0停止输入;数字不为,重新分配堆空间大小,新大小是原有基础上加一个int类型的大小。输入结束,输出算式时,同样遇到0算运算结束。例:
根据输入情况,效果图不同:
效果图仅供参考。