Realloc 别忘了

发布时间:2026/10/14 9:32:14

Realloc 别忘了 目录1. 函数原型与头文件2. 核心行为四种情况3. 数据保留规则4. 关键返回值与错误处理必看5. 典型使用场景与性能提示6. 完整代码示例7. 总结最佳实践清单realloc是 C 语言标准库中用于动态内存重分配的核心函数。它的作用就是调整之前通过malloc、calloc或realloc本身分配的内存块大小。下面从基础用法、核心行为、与calloc的区别到安全注意事项为你全面讲解。1. 函数原型与头文件#include stdlib.h void *realloc(void *ptr, size_t new_size);ptr指向之前分配的内存块的指针。如果为NULL则行为等同于malloc(new_size)。new_size请求的新内存大小以字节为单位。2. 核心行为四种情况realloc的执行逻辑非常灵活主要分四种情况情况ptr状态new_size行为1. 扩大内存有效指针 原大小尝试在原内存块后面追加空间。如果空间不足则另找新地复制旧数据释放旧地返回新地。2. 缩小内存有效指针 原大小直接截断多余部分返回原指针通常。注意被截掉的数据无法恢复且不会释放给操作系统通常由进程内部的内存池管理。3. 新分配NULL 0等同于malloc(new_size)返回新内存地址。3. 数据保留规则这是realloc最重要的特性之一保留原内存块中新旧大小中较小者的数据会被完整保留。新增如果内存扩大了新增加的部分不会初始化内容随机。丢弃如果内存缩小了被裁掉的部分数据会被丢弃。4. 关键返回值与错误处理必看这是实际开发中最容易出错的地方。int *p (int*)malloc(10 * sizeof(int)); // ... 使用 p ... // 错误做法直接赋值给原指针 p (int*)realloc(p, 20 * sizeof(int)); // 如果 realloc 失败返回 NULL原指针 p 丢失内存泄漏 // 正确做法使用临时指针 int *new_p (int*)realloc(p, 20 * sizeof(int)); if (new_p NULL) { // 内存分配失败p 依然指向原内存块可以继续使用或释放 perror(realloc failed); // free(p); // 根据业务决定是否退出或继续 exit(EXIT_FAILURE); } p new_p; // 安全更新核心原则永远不要将realloc的返回值直接赋给原指针必须先用临时变量检查是否为NULL。5. 典型使用场景与性能提示场景动态数组扩容如 ArrayList、Vector 的底层实现。性能陷阱当原内存块后面空间不足时realloc会移动整个内存块拷贝数据。如果频繁进行小幅扩容如每次加 1会导致大量的拷贝开销和内存碎片。最佳实践采用指数增长策略如每次扩为原来的 2 倍以分摊拷贝成本。6. 完整代码示例#include stdio.h #include stdlib.h int main() { int *arr (int*)malloc(3 * sizeof(int)); if (!arr) return 1; // 初始化 for (int i 0; i 3; i) arr[i] i; // 安全扩容到 5 个 int int *tmp (int*)realloc(arr, 5 * sizeof(int)); if (!tmp) { free(arr); return 1; } arr tmp; // 新增元素未初始化需要手动赋值 arr[3] 100; arr[4] 200; // 打印0 1 2 100 200 for (int i 0; i 5; i) printf(%d , arr[i]); free(arr); return 0; }7. 总结最佳实践清单必检 NULL使用临时指针接收返回值失败后原指针依然有效。不要用new_size 0这是未定义行为请用free释放内存。切勿重复释放如果realloc移动了内存一般说内存移动 是指扩容后不够 重新找了个新的地方吧会自动释放旧指针你只需要释放返回的新指针。谨慎用于缩小缩小内存虽然通常成功但操作系统不一定回收物理内存可能导致进程内存占用居高不下realloc缩小内存时释放的空间通常只回到进程内部的堆管理器内存池并不会立即通过系统调用如brk或munmap归还给操作系统。这意味着即使你从 1GB 缩小到 10MB通过top或任务管理器看到的进程常驻内存RSS占用可能依然很高。这部分空闲内存会被堆管理器保留留待后续的malloc请求重用。
延伸阅读

更多相关文章

2026/10/14 9:27:14

STEP 7:程序块保护

使用STEP 7编程工具,如果想对特定的程序块进行加密,可以采用程序块加密方式,此种加密方式分为两种: KNOW_HOW_PROTECT Block Privacy1 KNOW_HOW_PROTECT保护程序块 KNOW_HOW_PROTECT加密程序块方式与CPU固件版本无关&#xff0c…

2026/10/14 9:27:14

Agent Skills多平台实战:从技能编排到生产落地的完整指南

1. 从标题拆解这门课到底在讲什么 1.1 三个关键词锁定课程核心定位 “IT爱学堂-慕课-Agent Skills 多平台应用实战「完结无密」”这个标题信息量其实挺大的,我把它拆成三块来看。 第一块是 Agent Skills ,这是整个课程的技术内核。Agent这个词这两年…

2026/10/14 9:27:14

孟德尔随机化分析工具开发:从基因组学到药物靶点筛选

1. 项目概述:孟德尔随机化分析工具开发背景 在基因组学与临床医学的交叉领域,孟德尔随机化(Mendelian Randomization, MR)已成为评估暴露因素与疾病因果关系的重要方法。作为一名长期从事生物信息学工具开发的工程师,我…

2026/10/14 9:27:14

自用 Agent 全面功能测试实战:四层拆解与避坑指南

1. 为什么我要给自己的 Agent 做一次全面功能测试说实话,自己搭的 Agent 用久了,很容易陷入一种“能用就行”的惯性。我最初做这个 Agent 的初衷很简单:把每天重复性的信息整理、任务拆解、内容草拟这几件事自动化掉。头两周确实爽&#xff0…

2026/10/14 9:22:13

SwiftUI Agent Skill实战:从流式会话到工具调用

做SwiftUI的Agent类应用,最容易被卡住的不是UI,而是“AI能力”和“App本体”之间那条又宽又深的沟。SwiftUI本身只是个声明式界面框架,它不负责网络请求、不负责流式解析、更不负责让智能体理解你的App里有哪些功能。所以当我看到“SwiftUI-A…

2026/10/13 5:19:27

Python调用Gemini Structured Outputs实现工单路由门禁

客服工单最怕的不是模型“答错一句话”,而是它给出一段看起来合理的说明,程序却从中猜错优先级。通俗做法是:要求模型只交 JSON(JavaScript Object Notation,轻量数据格式),再让代码验证它。Gem…

2026/10/13 17:09:18

Spring Boot超市进销存系统毕设实战:从需求拆解到答辩通关

最近带的一个学生项目组里,有A同学跑来问我:选什么毕设题目最稳妥,既能让评审老师觉得工作量够,又不会在答辩时被问到语无伦次。我第一反应就是推荐基于Spring Boot的超市仓库管理系统——也就是超市进销存系统。这个题目乍一看平…

2026/10/14 2:32:55

Flutter StatefulWidget 生命周期核心解析

很多刚开始接触 Flutter 的朋友,在看完一堆“Hello World”和基础组件之后,大概率都会撞上同一堵墙:StatefulWidget 里那堆 initState、build、dispose 方法,到底什么时候被调用?为什么顺序是那样?在里面到…

2026/10/14 0:00:33

DFS算法解决飞机降落调度问题实战

1. 项目背景与核心思路飞机降落问题是一个经典的调度优化场景,也是算法竞赛和面试中的高频题目。这个题目要求我们合理安排多架飞机的降落顺序和时间,确保所有飞机都能安全着陆而不发生冲突。在实际航空管制中,这类问题直接关系到飞行安全和机…

2026/10/14 0:00:33

macOS/iOS高精度计时:mach_absolute_time原理与实战

1. 项目概述:为什么mach_absolute_time是 macOS/iOS 时间测量的“黄金标准”在 macOS 和 iOS 开发中,我见过太多人用CFAbsoluteTimeGetCurrent()或NSDate.timeIntervalSinceReferenceDate做性能打点,结果在高精度场景下被系统时钟跳变、NTP 同…

2026/10/14 0:00:33

SCORM课件演示与测试全解析:从API通信到自动化验证

简介:这是一套遵循SCORM标准的交互式课件演示与测试资源,面向E-Learning课程开发者、LMS平台测试人员及在线教学从业者,用于验证课件在不同学习管理系统中的识别、传递与跟踪能力。压缩包共28个文件,约12.07MB,以swf动…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑