亿迅智能制造网
工业4.0先进制造技术信息网站!
首页 | 制造技术 | 制造设备 | 工业物联网 | 工业材料 | 设备保养维修 | 工业编程 |
home  MfgRobots >> 亿迅智能制造网 >  >> Industrial programming >> C语言

C 语言 realloc() 完全指南:语法、最佳实践与实战案例

什么是 realloc()?

realloc()(re-allocation)用于调整已分配内存块的大小——既可扩大也可缩小——并在可能的情况下保留原有数据。它是实现动态数组、字符串缓冲区自动增长的核心工具,声明于 <stdlib.h>。

函数原型

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

核心行为与关键点

  1. 地址可能改变:扩容时若原址后空间不足,realloc 会分配新块、拷贝数据、释放旧块,返回新地址。必须用临时变量接收返回值,防止失败时丢失原指针导致内存泄漏。
  2. 数据保留范围:保留 min(old_size, new_size) 字节的内容。缩小时尾部数据丢失;扩容时新增区域内容不确定(非零初始化)。
  3. 失败安全:失败返回 NULL 且不释放原块,原指针仍有效,必须继续持有以便后续释放或重试。
  4. ptr 为 NULL 时等价 malloc(new_size);new_size 为 0 时等价 free(ptr)(C 标准允许返回 NULL 或唯一指针,不可解引用)。

实战案例 1:字符串缓冲区动态扩容

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

int main(void) {
    char *buf = malloc(10);
    if (!buf) { perror("malloc"); return EXIT_FAILURE; }

    strcpy(buf, "Programming");
    printf("%s\n", buf);                 // Programming

    char *tmp = realloc(buf, 20);        // 扩容至 20 字节
    if (!tmp) {
        free(buf);                       // 失败时原块仍有效,需释放
        perror("realloc");
        return EXIT_FAILURE;
    }
    buf = tmp;                           // 更新指针
    strcat(buf, " in C");
    printf("%s\n", buf);                 // Programming in C

    free(buf);
    return EXIT_SUCCESS;
}

实战案例 2:整型动态数组扩容

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

int main(void) {
    int *arr = malloc(10 * sizeof(int));
    if (!arr) { perror("malloc"); return EXIT_FAILURE; }

    // 使用数组...
    for (int i = 0; i < 10; ++i) arr[i] = i * i;

    int *tmp = realloc(arr, 50 * sizeof(int));   // 扩容至 50 个 int
    if (!tmp) {
        free(arr);
        perror("realloc");
        return EXIT_FAILURE;
    }
    arr = tmp;
    printf("Array resized successfully\n");

    // 新增元素初始化
    for (int i = 10; i < 50; ++i) arr[i] = -1;

    free(arr);
    return EXIT_SUCCESS;
}

实战案例 3:实现动态数组(Vector)核心逻辑

typedef struct {
    int *data;
    size_t size;      // 当前元素数
    size_t capacity;  // 当前分配容量
} IntVec;

void vec_push(IntVec *v, int val) {
    if (v->size == v->capacity) {
        size_t new_cap = v->capacity ? v->capacity * 2 : 4;  // 倍增策略
        int *tmp = realloc(v->data, new_cap * sizeof(int));
        if (!tmp) { /* 处理 OOM */ return; }
        v->data = tmp;
        v->capacity = new_cap;
    }
    v->data[v->size++] = val;
}

关键设计:倍增策略(×2 或 ×1.5)使摊还时间复杂度为 O(1);realloc 失败时不修改原结构体,保持强异常安全。

实战案例 4:缩容与释放

// 缩容至实际大小(去除多余容量)
int *tmp = realloc(arr, v->size * sizeof(int));
if (tmp) arr = tmp;   // 缩容失败不影响正确性,仅保留多余容量

实用技巧与最佳实践

常见错误对照

错误代码后果修正
ptr = realloc(ptr, new_sz);失败时 ptr 变 NULL,原块泄漏用临时变量接收
假设扩容后地址不变指针失效,访问野指针始终用返回值更新指针
缩容后访问原有效范围外数据读取已释放/不可达内存严格按新 size 访问
对非堆指针调用 realloc未定义行为(崩溃/静默损坏)仅对 malloc/calloc/realloc 返回指针调用

调试与分析工具

总结

realloc() 是 C 语言构建可变长数据结构的利器。核心铁律:用临时变量接收返回值、检查 NULL、理解地址可能变、新增区域不清零、缩容丢尾部数据。掌握这些,即可安全高效地实现动态数组、字符串构建器、缓冲区管理等核心组件。

C语言

  1. 灭火器实战指南:何时使用与标准操作流程(PASS原则)
  2. 喷枪作业进阶指南:压力调节、喷型选择、匀速作业三步法,实现均匀无漏涂装
  3. 热敏电阻测温轻松上手:Arduino 分步实战教程
  4. 刀具磨床实战技法指南:从入门到精通
  5. 善用Azure DevOps:加速交付的实战最佳实践
  6. 钼如何塑造现代工业:用途、优势与供应动态
  7. 用环氧树脂将完成拼图封装成永恒艺术品
  8. C 语言 calloc() 详解:零初始化动态分配原理与实战案例
  9. C 语言 free() 函数实战指南:正确释放动态内存、防泄漏与避坑全解析
  10. 使用VHDL不纯函数提升FSM可读性与可维护性
  11. 掌握VHDL函数:高效设计实战指南
  12. 在VHDL中使用过程:用可复用代码简化设计