C语言动态分配内存的malloc()、calloc()、realloc()三者区别

发布于:2025-02-10 ⋅ 阅读:(26) ⋅ 点赞:(0)

前言

  malloc()calloc()realloc() 都是 C 语言中的动态内存分配函数,它们的作用都是在堆上分配内存,但它们的行为和用途有所不同。下面详细介绍它们的区别。

1. malloc()(Memory Allocation 内存分配)

malloc() 用于分配一块指定大小的内存区域。分配的内存内容是未初始化的,意味着它的内容是随机的(不确定的)。

语法

void* malloc(size_t size);
  • size:请求分配的内存块的字节数。
  • 返回值:返回指向分配内存的指针,如果分配失败,则返回 NULL

特点

  • 分配的内存大小是通过 size 参数指定的。
  • 内存未初始化,内存的内容是随机的(即不确定的垃圾值)。
  • 返回 void*,需要强制类型转换成目标类型指针。

示例

int* ptr = (int*)malloc(10 * sizeof(int));  // 分配 10 个 int 大小的内存
if (ptr == NULL) {
    printf("内存分配失败\n");
} else {
    // 使用分配的内存
}

2. calloc()(Contiguous Allocation 连续分配

calloc() 用于分配一个指定数量的内存块,并且将这块内存初始化为 0。它的功能类似于 malloc(),但它还会初始化分配的内存。

语法

void* calloc(size_t num, size_t size);
  • num:要分配的元素的数量。
  • size:每个元素的字节大小。
  • 返回值:返回指向分配内存的指针,如果分配失败,则返回 NULL

特点

  • 分配的内存块大小是 num * size
  • 内存初始化为 0,确保分配的内存不会包含垃圾值。
  • 返回 void*,需要强制类型转换成目标类型指针。

示例

int* ptr = (int*)calloc(10, sizeof(int));  // 分配 10 个 int 大小的内存并初始化为 0
if (ptr == NULL) {
    printf("内存分配失败\n");
} else {
    // 使用分配的内存,所有元素初始为 0
}

3. realloc()(Reallocation 重新分配)

  realloc() 用于重新调整已经分配的内存块的大小。它可以增加或减少内存的大小。如果内存地址发生变化(例如扩展后的内存空间无法容纳在原来的位置),realloc() 会返回一个新的指向内存的指针。如果无法扩展内存,realloc() 返回 NULL,并且原始内存块保持不变。

语法

void* realloc(void* ptr, size_t new_size);
  • ptr:指向已分配内存块的指针。
  • new_size:请求的新内存大小(字节数)。
  • 返回值:返回指向重新分配后内存的指针。如果分配失败,返回 NULL,原内存块保持不变。

特点

  • realloc() 会根据 new_size 调整内存块的大小。
  • 扩展内存时,如果原内存块不能容纳更多空间,realloc() 会返回一个新的指针。
  • 缩小内存时,realloc() 会减少内存块的大小,并保留原有的数据。
  • 如果 realloc() 失败,返回 NULL,原来的内存不会被释放。

示例

int* ptr = (int*)malloc(10 * sizeof(int));  // 初始分配 10 个 int 大小的内存
if (ptr == NULL) {
    printf("内存分配失败\n");
}

// 重新调整内存块大小,增加到 20 个 int 大小
ptr = (int*)realloc(ptr, 20 * sizeof(int));
if (ptr == NULL) {
    printf("内存重新分配失败\n");
} else {
    // 使用新的内存块
}

4. 三者的区别总结

特性 malloc() calloc() realloc()
功能 分配一块指定大小的内存块 分配并初始化为 0 的内存块 重新调整已经分配内存的大小(增加或减少)
初始化 不初始化内存,内存内容是垃圾值 将分配的内存初始化为 0 新分配的内存会初始化为 0(仅当扩展时有新内存分配)
返回值 返回 void* 类型,需强制转换 返回 void* 类型,需强制转换 返回重新分配后的指针,若失败则返回 NULL
用法 用于分配已知大小的内存块 用于分配已知大小的内存并初始化为 0 用于调整已分配内存的大小
内存管理 不会释放内存,需手动释放 不会释放内存,需手动释放 返回新的内存块,若失败则返回 NULL,不会释放原内存
适用场景 仅需要分配内存,但不关心初始化内容 需要初始化内存为 0 需要调整原内存块的大小

5. 总结

  • malloc():分配内存,但不初始化内容,适用于只需要分配内存而不关心初值的情况。
  • calloc():分配并初始化内存,适用于需要内存初始化为零的情况。
  • realloc():重新调整内存块的大小,适用于已经分配内存后需要扩大或缩小内存的情况。

在我们写c程序时,选择合适的内存分配函数有助于提高程序的效率和安全性。


网站公告

今日签到

点亮在社区的每一天
去签到