动态内存调配概述
C语言中的所有操作都是基于内存的,变量和数组都是内存的别名,如何调配这个内存由编译器在变异期间决定的。
如定义数组时必须指定数组的长度,因而数组长度是在编译期就必须确定。
然而某些时候程序在运行中,可能须要应用一些额定的内存空间。
malloc和free
malloc所调配的内存是一块间断的内存,以字节为单位,并且不带任何的类型信息。
free用于将动态内存偿还零碎。其原型如下:
void *malloc(size_t size);void free(void *p);
留神:
- malloc理论调配的内存可能会比申请的稍多一点,但不能依赖于这一点;
- 当申请的动态内存无奈满足时malloc返回NULL;
- 当free的参数为NULL时,函数间接返回。
因而无论如何应用malloc时必须查看返回值是否可用。
calloc和realloc
calloc与realloc相似,都可用于内存申请。原型如下:
void * calloc(size_t num,size_t size);
参数:
- num 须要申请的内存个数
- size 每个内存块的大小
* 为NULL申请失败,非NULL申请胜利,其总空间为num*size。
void * realloc(void *p,size_t new_size);
参数:
- p 原内存空间
- new_size 所需新的内存空间
返回值:
- 为NULL申请失败,非NULL申请胜利。
由上可知calloc和realloc均可返回申请的内存信息,与malloc雷同应用前须要查看返回值是否可用。
与malloc不同,calloc返回的内存将被初始化为0,而realloc则是用于批改原已调配的内存大小,因而应用realloc的返回值即为新调配的内存空间,当第一个参数为NULL时,则realloc等价于malloc。
示例如下:
#include<stdio.h>#include<malloc.h>#include<string.h>#include<assert.h>#include<errno.h>#include<stdlib.h>int main(void){ int i; int *pi = (int*)malloc(5*sizeof(int)); short *ps = (short*)calloc(5,sizeof(short)); assert(pi&&ps); for(i = 0;i < 5;i++){ printf("pi[%d] = %d,ps[%d] = %d\n",i,pi[i],i,ps[i]); } pi = (int*)realloc(pi,10*sizeof(int)); if(NULL == pi){ free(pi); free(ps); perror("realloc\n"); exit(EXIT_FAILURE); } for(i = 0;i < 10;i++){ printf("pi[%d] = %d\n",i,pi[i]); } free(pi); free(ps); return 0;}
由上可知动态内存调配是C语言中的弱小性能,只须可能在须要的时候动静的申请内存。
总结:
- malloc单纯的从零碎中申请固定字节的内存;
- calloc能以某种类型或指定单位大小来申请内存,并初始化为0;
- realloc用于重置内存大小。
那么问题来了
malloc(0)的返回值是啥?
一般来说,malloc如返回值为NULL则malloc失败,否则将会返回一个无效的内存地址,能够被free掉,而这个无效的内存地址的无效内存空间为0,因为空间为0的内存空间也是一个内存对象,与NULL的含意不同。
calloc(0,0)的返回值又是啥?
同malloc。
realloc(p<不为空>,0)呢?
同free。
email: MingruiZhou@outlook.com