授课语音

C语言中的内存管理

在C语言中,内存管理是编程的重要环节,尤其是在动态分配内存时。标准库提供了四个常用的内存管理函数:malloccallocreallocfree。正确使用这些函数可以提高程序的效率和灵活性,但误用可能导致内存泄漏或未定义行为。


1. malloc:分配指定大小的内存

介绍

  • malloc(Memory Allocation)用于动态分配一块指定大小的内存。
  • 它返回一个指向分配内存的指针,类型为 void *,需要显式转换为适当的指针类型。
  • 分配的内存内容未初始化。

函数原型

void *malloc(size_t size);

参数说明

  • size:需要分配的内存大小(以字节为单位)。

返回值

  • 成功:返回分配内存的指针。
  • 失败:返回 NULL

代码案例

#include <stdio.h>
#include <stdlib.h>

int main() {
    // 动态分配一个包含10个整数的内存块
    int *arr = (int *)malloc(10 * sizeof(int));
    
    // 检查内存是否分配成功
    if (arr == NULL) {
        printf("内存分配失败!\n");
        return 1; // 退出程序
    }

    // 初始化分配的内存
    for (int i = 0; i < 10; i++) {
        arr[i] = i + 1; // 将数组元素初始化为1到10
    }

    // 输出数组内容
    printf("数组内容:");
    for (int i = 0; i < 10; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");

    // 释放内存
    free(arr);

    return 0;
}

中文注释:

  • 使用 malloc 动态分配了一个存储10个整数的内存块。
  • 检查返回的指针是否为 NULL,确保分配成功。
  • 使用循环对内存进行初始化并打印内容。
  • 最后调用 free 释放分配的内存。

2. calloc:分配并初始化内存

介绍

  • calloc(Contiguous Allocation)分配一块连续的内存,并将内存初始化为零。
  • 常用于需要清零的数组分配。

函数原型

void *calloc(size_t num, size_t size);

参数说明

  • num:要分配的元素数量。
  • size:每个元素的大小(以字节为单位)。

返回值

  • 成功:返回分配内存的指针。
  • 失败:返回 NULL

代码案例

#include <stdio.h>
#include <stdlib.h>

int main() {
    // 使用 calloc 分配10个整数的内存
    int *arr = (int *)calloc(10, sizeof(int));

    // 检查内存是否分配成功
    if (arr == NULL) {
        printf("内存分配失败!\n");
        return 1; // 退出程序
    }

    // 输出数组内容,初始化为0
    printf("数组内容:");
    for (int i = 0; i < 10; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");

    // 释放内存
    free(arr);

    return 0;
}

中文注释:

  • 使用 calloc 动态分配内存,区别于 malloc,分配的内存被自动初始化为零。
  • 验证分配是否成功并输出初始化的数组内容。
  • 调用 free 释放内存。

3. realloc:调整已分配内存的大小

介绍

  • realloc 用于调整之前分配的内存块大小。
  • 如果新大小大于原大小,新分配的部分内容未初始化;如果小于原大小,多余部分会被释放。

函数原型

void *realloc(void *ptr, size_t size);

参数说明

  • ptr:指向已分配内存的指针,若为 NULL,行为类似 malloc
  • size:新的内存大小(以字节为单位)。

返回值

  • 成功:返回调整后的内存指针。
  • 失败:返回 NULL

代码案例

#include <stdio.h>
#include <stdlib.h>

int main() {
    // 初始分配5个整数的内存
    int *arr = (int *)malloc(5 * sizeof(int));

    // 检查内存是否分配成功
    if (arr == NULL) {
        printf("内存分配失败!\n");
        return 1; // 退出程序
    }

    // 初始化分配的内存
    for (int i = 0; i < 5; i++) {
        arr[i] = i + 1;
    }

    // 调整内存大小为10个整数
    arr = (int *)realloc(arr, 10 * sizeof(int));
    if (arr == NULL) {
        printf("内存重新分配失败!\n");
        return 1; // 退出程序
    }

    // 初始化新增的内存部分
    for (int i = 5; i < 10; i++) {
        arr[i] = i + 1;
    }

    // 输出数组内容
    printf("调整后数组内容:");
    for (int i = 0; i < 10; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");

    // 释放内存
    free(arr);

    return 0;
}

中文注释:

  • 初始分配了一个包含5个整数的内存块。
  • 使用 realloc 调整大小为10个整数,并初始化新增部分。
  • 确保调整成功后,释放内存。

4. free:释放分配的内存

介绍

  • free 用于释放由 malloccallocrealloc 分配的内存。
  • 释放后指针变为悬空指针,应设置为 NULL

函数原型

void free(void *ptr);

参数说明

  • ptr:指向要释放的内存的指针。

注意事项

  • 释放空指针(NULL)是安全的。
  • 不要释放未动态分配的内存,否则会导致未定义行为。

代码案例

#include <stdio.h>
#include <stdlib.h>

int main() {
    int *arr = (int *)malloc(5 * sizeof(int));
    if (arr == NULL) {
        printf("内存分配失败!\n");
        return 1;
    }

    // 使用内存...
    free(arr); // 释放内存
    arr = NULL; // 避免悬空指针

    return 0;
}

中文注释:

  • 分配并释放内存。
  • 将指针置为 NULL 避免后续误用。

总结

  • 使用 malloccalloc 动态分配内存,前者不初始化内存,后者初始化为零。
  • 使用 realloc 调整已分配内存大小。
  • 使用 free 释放动态分配的内存。
  • 注意检查返回值,确保内存分配成功并避免内存泄漏。
去1:1私密咨询

系列课程: