所谓动态内存分配(Dynamic Memory Allocation)就是指在程序执行的过程中动态地分配或者回收存储空间的分配内存的方法。动态内存分配不像数组静态内存分配方法那样需要预先分配存储空间,而是由系统根据程序的需要即时分配,且分配的大小就是程序要求的大小。
以数组举例,在目前的编程学习中 float arr[100] 定义这样一个数组,在学习中使用空间足够;但是在以后工作甚至是学习的深入之后,空间可能会不足,会有数组越界的情况发生。所以,为了应对这样的情况,就需要引入动态内存这样的概念,即需要多大申请多大,使用之后还原即可。
这两个函数分别执行动态内存和释放。
当一个程序另外需要一些内存时,它就调用malloc函数,malloc从内存池中提取一块合适的内存。并向该程序返回一个指向这块内存的指针。这块内存此时并没有以任何方式进行初始化。
如果要对其进行初始化,要么自己动手进行初始化,要么使用calloc()函数。
当一块以前分配的内存不在使用时,程序调用free函数把它归还给内存池供以后使用。
函数原型:
两个函数都包含在 <stdlib.h>的头文件中:
malloc
void *malloc(size_t size);1.malloc的参数就是需要分配的内存字节数。如果内存池中的可用内存可以满足这个需求,malloc就返回一个指向被分配的内存块起始位置的指针。
2.如果内存池是空的,或者它的可用内存无法满足要求时。在该情况下,malloc()函数向操作系统请求,要求得到更多地内存,并在这块内存上执行分配任务。如果操作系统无法向malloc提供更多的内存,malloc就返回一个NULL指针。因此,要对每个从malloc返回的指针都进行检查,确保它并非NULL是非常重要的。
3.malloc并不知道请求的内存需要存储的是整型、浮点值、结构还是数组。Malloc返回一个类型为void *的指针。在标准中表示一个void *类型的指针可以转换为其他任何类型的指针。因此,在使用前,要进行强制类型转换。
free
void free(void *pointer)free的参数必须要么是NULL,要么是一个先前从malloc,calloc或realloc返回的数值。想free传递一个NULL参数不会产生任何效果。
还有两个内存分配函数,calloc和realloc。
函数原型:
calloc
void *calloc(size_t num_elements,size_t element_size);1.calloc也用于分配内存。malloc和calloc之间的区别是后者在返回指向内存的指针之前把它初始化为0。但如果程序只是想把一些值存储到数组中,那么这个初始化过程纯属浪费时间。
2.calloc和malloc之间另一个较小的区别是它们请求内存数量的方式不同。calloc的参数包括所需元素的数量和每个元素的字节数。根据这些值,它能够计算出总共需要分配的内存。
relloc
void realloc(void *ptr,size_t new_size);realloc函数用于修改一个原先已经分配的内存块大小。
1>使用这个函数,你可以使一块内存扩大或缩小。如果它用于扩大一个内存块,那么这块内存原先的内容依然保留,新增加的内存添加到原先内存块的后面,新内存并未以任何方法进行初始化。
2>如果它用于缩小一块内存块,该内存块尾部的部分内存便被拿掉,剩余部分内存的原先内容依然保留。
3>如果原先的内存块无法改变大小,realloc将分配另一块正确大小的内存,并把原先那块内存的内容复制到新的块上。因此,在使用realloc之后,就不能再使用指向旧内存的指针,而是应该该用realloc所返回的新指针。
4>如果realloc函数的第一个参数是NULL,那么它的行为就和malloc一模一样。