C语言 realloc 函数详解

realloc 是C标准库中用于动态内存重新分配的函数,定义在 <stdlib.h> 头文件中。它用于调整之前分配的内存块的大小。

函数原型

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

参数说明

  • ptr:指向先前由 malloccallocrealloc 分配的内存块的指针
  • size:新的内存块大小(以字节为单位)

返回值

  • 成功:返回指向重新分配的内存块的指针
  • 失败:返回 NULL,且原内存块保持不变

功能描述

realloc 的行为取决于参数:

  1. ptr NULL
    • 等同于 malloc(size)
    • 分配一块新内存
  1. size 0 ptr 不为 NULL
    • 等同于 free(ptr)
    • 释放原内存块
    • 返回 NULL
  1. 常规情况(ptr size 均有效)
    • 尝试调整内存块大小
    • 可能原地扩展/缩小,也可能移动内存块到新位置
    • 保留原内存块内容(直到新旧大小的较小值)

使用示例

示例1:基本使用

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

void init_array(int ** array, int low_index, int high_index)
{
    for (int i = low_index; i < high_index; i++)
    {
        (*array)[i] = i + 2;
    }
}

void print_array(const int * array, int high_index)
{
    printf("---print_array:-------\n");
    for (int i = 0; i < high_index; i++)
    {
        printf("arr[%d]=%d\n", i, (array)[i]);
    }
}

int main()
{
    int *arr = malloc(5 * sizeof(int));
    if (arr == NULL)
    {
        printf("alloc failed");
        return 1;
    }
    init_array(&arr, 0, 5);
    print_array(arr, 5);

    int *new_arr = realloc(arr, 10 * sizeof(int));
    if (new_arr == NULL)
    {
        perror("reallocate failed\n");
        free(arr);  // 此时原指针仍有效,需释放
        return 1;
    }

    arr = new_arr;
    print_array(arr, 10);

    init_array(&arr, 5, 10);

    print_array(arr, 10);

    free(arr);
    return 0;
}

示例2:安全使用模式

void *safe_realloc(void *ptr, size_t new_size) {
    void *new_ptr = realloc(ptr, new_size);
    if (new_ptr == NULL && new_size != 0) {
        perror("realloc failed");
        exit(EXIT_FAILURE);
    }
    return new_ptr;
}

重要注意事项

1,使用临时变量保存结果,成功后再更新原指针

2,内存移动

  • realloc 可能移动内存块到新地址
  • 所有指向原内存块的指针都会失效
  • 必须使用新指针作为返回值

3,内容保留

  • 新内存块中,原内容会保留到新旧大小的较小值
  • 新增部分的内容是未初始化的

4,错误处理

  • 必须检查返回值是否为 NULL
  • 失败时原内存块仍有效,需要手动释放

5,性能考虑

  • 频繁的 realloc 调用可能导致内存碎片
  • 建议使用指数增长策略(如每次容量翻倍)

6,多线程安全

  • realloc 本身不是线程安全的
  • 在多线程环境中需要额外同步

常见错误

错误1:直接覆盖原指针

arr = realloc(arr, new_size);  // 错误!如果失败会丢失原指针

错误2:忽略返回值检查

realloc(ptr, new_size);  // 错误!不检查是否成功

最佳实践

  1. 总是检查 realloc 的返回值
  2. 使用临时变量保存结果,成功后再更新原指针
  3. 对于需要频繁调整大小的数据结构,考虑更高效的内存管理策略
  4. 释放内存时,将指针设为 NULL 避免悬垂指针
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值