在 C 语言中,从堆(heap)中动态分配内存一般有两种方式,一种是通过 calloc
,另一种是通过 malloc
。那么这两种动态分配内存的方式有什么区别呢?
首先,最重要的区别在于分配的内存是否有初始化。malloc
动态分配指定大小(按字节算)块(block)的内存,并返回内存块的起始地址指针。但 malloc
并不初始化已经分配好的内存。如果你尝试去访问 malloc
申请的内存块内容,访问到的是垃圾值(garbage values)。而 calloc
则会把申请的内存块默认初始化为 0,因此访问的话就会得到0的值。
再来看两个接口原型的区别:
void * malloc( size_t size );
void * calloc( size_t num, size_t size );
malloc
只接收一个参数,用来指定申请的内存大小(按字节算)。而 calloc
则接收两个参数,第一个参数指定内存块的数量,第二个参数指定每个内存块的大小。比如,要动态分配一个长度为5的 int
类型数组,并把数组里的每一个元素都初始化为 0,两个接口的用法区别如下:
int * arr = (int *)malloc(5 * sizeof(int));
memset(arr, 0, 5 * sizeof(int));
free(arr);
int * arr = (int *)calloc(5, sizeof(int));
free(arr);
因为 malloc
并不默认初始化,因此需要额外调用 memset
方法来初始化。
那么,一般情况下,我们到底是使用 malloc
还是 calloc
呢?从上面的分析看,calloc
不仅需要分配内存,还需要把内存值都初始化为 0,因此效率肯定是不如 malloc
的。如果你需要把一块已经存在的内存拷贝到新申请的同样大小的内存块中,那么使用 malloc
显然更优,因为你不需要事先把内存值都置为 0。而如果申请的内存块需要默认全部初始化为 0,那么显然 calloc
使用起来更简洁些。