Jupyter AI

9 动态内存管理之 calloc/realloc 使用

📅 发表日期: 2024年8月10日

分类: 💻C++ 高级

👁️阅读: --

在C语言的动态内存管理中,前一篇我们讨论了 mallocfree 函数,它们用于在堆上动态分配和释放内存。而在这一节中,我们将重点探讨 callocrealloc 的使用,这两者与 mallocfree 共同构成了动态内存管理的基础。

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. 总结

通过 callocrealloc,我们可以更灵活地进行内存管理。calloc 适用于需要初始化为零的内存分配,而 realloc 则允许我们在运行时动态调整已分配内存的大小。这些函数让我们的程序能够更有效地处理动态数据结构,比如数组和链表等。

在下一篇中,我们将讨论如何识别内存泄漏,确保我们的动态内存使用更加安全和高效。