C 语言的动态内存管理

C 语言的动态内存管理是通过 malloccallocreallocfree 这四个标准库函数来完成的,这些函数定义在 <stdlib.h> 头文件中。

1. 动态内存管理的基本函数

函数作用
malloc(size_t size)分配 指定字节 的内存,未初始化
calloc(size_t num, size_t size)分配 指定数量和大小 的内存,并初始化为 0
realloc(void *ptr, size_t new_size)重新调整已分配的内存大小
free(void *ptr)释放已分配的内存

2. malloc()(分配内存,不初始化)

malloc 分配一块指定大小的内存,并返回指向该内存的指针。
⚠️ 注意:malloc 只分配空间,不会初始化内存!

示例:使用 malloc 分配动态数组

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

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

    // 赋值并输出
    for (int i = 0; i < 5; i++) {
        arr[i] = i + 1;
        printf("%d ", arr[i]);  // ⚠️ malloc 分配的内存未初始化,建议手动赋值!
    }
    printf("\n");

    free(arr);  // 释放内存
    return 0;
}

输出:

1 2 3 4 5

3. calloc()(分配并初始化)

calloc(n, size) 分配 n * size 字节的内存,并初始化为 0

示例:使用 calloc 分配动态数组

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

int main() {
    int *arr = (int *)calloc(5, sizeof(int));  // 分配 5 个 int,并初始化为 0
    if (arr == NULL) {
        printf("内存分配失败!\n");
        return 1;
    }

    // 输出默认值(全部初始化为 0)
    for (int i = 0; i < 5; i++) {
        printf("%d ", arr[i]);  // 结果全部是 0
    }
    printf("\n");

    free(arr);  // 释放内存
    return 0;
}

输出:

0 0 0 0 0

calloc 适用于初始化为 0 的情况,如二维数组、结构体等。


4. realloc()(调整已分配的内存)

realloc(ptr, new_size) 调整 之前 malloccalloc 分配的内存大小。

示例:动态扩展数组

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

int main() {
    int *arr = (int *)malloc(3 * sizeof(int));  // 分配 3 个 int
    if (arr == NULL) return 1;

    arr[0] = 1; arr[1] = 2; arr[2] = 3;

    // 重新调整大小为 5 个 int
    arr = (int *)realloc(arr, 5 * sizeof(int));
    if (arr == NULL) return 1;

    arr[3] = 4;
    arr[4] = 5;

    for (int i = 0; i < 5; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");

    free(arr);
    return 0;
}

输出:

1 2 3 4 5

⚠️ 注意:

  • realloc 可能会移动数据,返回的新指针可能不同于原来的指针,所以要用 arr = realloc(arr, new_size) 重新赋值
  • 如果 realloc 失败,它会返回 NULL,原来的数据不会丢失,但要确保代码能正确处理。

5. free()(释放内存)

所有使用 malloccallocrealloc 分配的内存,必须使用 free 释放,否则会导致内存泄漏

示例:正确释放内存

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

int main() {
    int *ptr = (int *)malloc(10 * sizeof(int));  
    if (ptr == NULL) return 1;

    free(ptr);  // 释放内存

    // 释放后指针仍然存储原来的地址,应该置 NULL
    ptr = NULL;  // 防止 "野指针" 问题

    return 0;
}

⚠️ 释放内存后,不要再使用该指针!

free(ptr);
printf("%d", *ptr);  // ❌ 释放后访问是"未定义行为"

6. 内存泄漏与最佳实践

内存泄漏的示例

如果 malloc 了内存但没有 free,会导致内存泄漏

void leakMemory() {
    int *p = (int *)malloc(100 * sizeof(int));
    // ❌ 忘记 free(p),导致内存泄漏!
}

如何避免内存泄漏?

使用 free 释放所有 malloc 的内存

int *p = (int *)malloc(100 * sizeof(int));
if (p != NULL) {
    free(p);  // 释放内存
    p = NULL; // 避免野指针
}

动态分配后立即 free

void example() {
    int *arr = (int *)malloc(10 * sizeof(int));
    if (!arr) return;

    // 业务逻辑...

    free(arr);  // 释放内存
}

使用智能指针(C++ 适用) 如果是 C++,可以用 std::unique_ptrstd::shared_ptr 自动管理内存:

#include <memory>

void example() {
    std::unique_ptr<int[]> arr(new int[10]);  // 自动释放,无需手动 free()
}

总结

函数作用初始化失败时返回
malloc(size)分配 size 字节❌ 不初始化NULL
calloc(n, size)分配 n * size 字节✅ 初始化为 0NULL
realloc(ptr, new_size)调整 ptr 指向的新大小❌ 可能部分保留数据NULL(失败时原数据仍然有
效)
free(ptr)释放 ptr 指向的内存

THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容