9 动态内存管理之 calloc/realloc 使用
在C语言的动态内存管理中,前一篇我们讨论了 malloc
和 free
函数,它们用于在堆上动态分配和释放内存。而在这一节中,我们将重点探讨 calloc
和 realloc
的使用,这两者与 malloc
和 free
共同构成了动态内存管理的基础。
1. calloc
的使用
calloc
是用于分配内存的函数,其声明如下:
void* calloc(size_t num, size_t size);
1.1 calloc
的特性
calloc
会分配num
个元素,每个元素的大小为size
字节。- 与
malloc
不同的是,calloc
会初始化分配的内存区域为零。 - 返回值是一个指向分配内存块的指针,如果分配失败,则返回
NULL
。
1.2 示例代码
以下是一个使用 calloc
的示例,演示如何分配一个数组并初始化。
#include <stdio.h>
#include <stdlib.h>
int main() {
int num_elements = 5;
// 使用 calloc 分配内存并初始化为0
int *array = (int*)calloc(num_elements, sizeof(int));
if (array == NULL) {
fprintf(stderr, "Memory allocation failed\n");
return 1;
}
// 打印数组内容
for (int i = 0; i < num_elements; i++) {
printf("array[%d] = %d\n", i, array[i]); // 应该打印出0
}
// 释放内存
free(array);
return 0;
}
在这个示例中,calloc
分配了 5 个 int
类型的元素,并将其初始化为 0。可以看到,打印的数组元素也是 0。
2. realloc
的使用
realloc
用于改变已经分配的内存块的大小,其函数原型如下:
void* realloc(void* ptr, size_t new_size);
2.1 realloc
的特性
realloc
可以用于将已经分配的内存块ptr
的大小更改为new_size
字节。- 如果
new_size
大于原来的大小,realloc
会尝试扩大内存块,并且未初始化部分的内容是未定义的。 - 如果
new_size
为零,则realloc
会释放内存块,返回NULL
。 - 如果扩展内存失败,
realloc
返回NULL
,并且原内存块保持不变。
2.2 示例代码
下面是一个使用 realloc
的示例,展示如何动态扩展内存。
#include <stdio.h>
#include <stdlib.h>
int main() {
int initial_size = 3;
int *array = (int*)malloc(initial_size * sizeof(int));
if (array == NULL) {
fprintf(stderr, "Initial memory allocation failed\n");
return 1;
}
for (int i = 0; i < initial_size; i++) {
array[i] = i + 1; // 初始化数组
}
// 打印初始数组
printf("Initial array: ");
for (int i = 0; i < initial_size; i++) {
printf("%d ", array[i]);
}
printf("\n");
// 扩大数组到新的大小
int new_size = 5;
array = (int*)realloc(array, new_size * sizeof(int));
if (array == NULL) {
fprintf(stderr, "Reallocation failed\n");
return 1;
}
// 初始化新增的元素
for (int i = initial_size; i < new_size; i++) {
array[i] = i + 1; // 继续初始化
}
// 打印扩展后的数组
printf("Resized array: ");
for (int i = 0; i < new_size; i++) {
printf("%d ", array[i]);
}
printf("\n");
// 释放内存
free(array);
return 0;
}
在这个示例中,我们首先使用 malloc
分配了三个 int
类型的元素,然后使用 realloc
将数组扩展到五个元素,并初始化了新添加的元素。
3. 总结
通过 calloc
和 realloc
,我们可以更灵活地进行内存管理。calloc
适用于需要初始化为零的内存分配,而 realloc
则允许我们在运行时动态调整已分配内存的大小。这些函数让我们的程序能够更有效地处理动态数据结构,比如数组和链表等。
在下一篇中,我们将讨论如何识别内存泄漏,确保我们的动态内存使用更加安全和高效。