calloc 与 realloc
calloc 分配内存并初始化为零,realloc 调整已分配内存的大小。这两个函数是 malloc 的补充,分别用于需要清零内存和需要动态调整大小的场景。
calloc
#include <stdlib.h>
/* 分配 10 个 int,全部初始化为 0 */
int *arr = calloc(10, sizeof(int));
if (arr != NULL) {
/* arr[0] 到 arr[9] 都是 0 */
for (int i = 0; i < 10; i++)
printf("%d ", arr[i]); /* 0 0 0 0 0 0 0 0 0 0 */
free(arr);
}
calloc(n, size) 等价于 malloc(n * size) + memset(ptr, 0, n * size),但 calloc 可能更高效(某些实现利用内存页已清零的特性)。
realloc
int *arr = malloc(10 * sizeof(int));
/* 使用 arr[0..9] */
/* 扩展到 20 个 int */
int *new_arr = realloc(arr, 20 * sizeof(int));
if (new_arr != NULL) {
arr = new_arr;
/* 使用 arr[0..19] */
free(arr);
} else {
/* 扩展失败,arr 仍然有效 */
free(arr);
}
realloc 的特殊用法
缩小内存:
int *arr = malloc(100 * sizeof(int));
arr = realloc(arr, 50 * sizeof(int)); /* 缩小到 50 个 */
释放内存(传 NULL):
int *arr = malloc(100);
realloc(arr, 0); /* 等价于 free(arr),但可移植性差 */
分配内存(传 NULL):
int *arr = realloc(NULL, 100); /* 等价于 malloc(100) */
常见错误
丢失原指针:
int *arr = malloc(10 * sizeof(int));
arr = realloc(arr, 20 * sizeof(int)); /* 危险! */
/* 如果 realloc 失败,arr 变为 NULL,原内存泄漏 */
/* 正确 */
int *new_arr = realloc(arr, 20 * sizeof(int));
if (new_arr != NULL)
arr = new_arr;
使用已释放的原内存:
int *arr = malloc(10 * sizeof(int));
int *new_arr = realloc(arr, 20 * sizeof(int));
arr[0] = 10; /* 危险:arr 可能已失效 */
最佳实践
- 需要清零时用
calloc realloc用临时指针接收返回值realloc失败时原内存仍然有效- 不要假设
realloc后原指针仍可用 - 缩小内存时数据可能截断