跳转到内容
主菜单
主菜单
移至侧栏
隐藏
导航
首页
最近更改
随机页面
MediaWiki帮助
代码酷
搜索
搜索
中文(中国大陆)
外观
创建账号
登录
个人工具
创建账号
登录
未登录编辑者的页面
了解详情
贡献
讨论
编辑“︁
C 语言 realloc 函数
”︁
页面
讨论
大陆简体
阅读
编辑
编辑源代码
查看历史
工具
工具
移至侧栏
隐藏
操作
阅读
编辑
编辑源代码
查看历史
常规
链入页面
相关更改
特殊页面
页面信息
外观
移至侧栏
隐藏
您的更改会在有权核准的用户核准后向读者展示。
警告:
您没有登录。如果您进行任何编辑,您的IP地址会公开展示。如果您
登录
或
创建账号
,您的编辑会以您的用户名署名,此外还有其他益处。
反垃圾检查。
不要
加入这个!
{{Note|本条目将详细讲解C语言中动态内存管理的重要函数'''realloc''',适合初学者和需要巩固该知识点的开发者。}} = realloc函数概述 = '''realloc'''(全称re-allocation)是C标准库(<stdlib.h>)中用于'''动态调整已分配内存块大小'''的函数。它解决了以下核心问题: * 当程序运行时发现原先分配的内存不足时,无需手动创建新内存块并复制数据 * 当分配的内存过大时,可以缩小内存块以减少内存占用 == 函数原型 == <syntaxhighlight lang="c"> void *realloc(void *ptr, size_t size); </syntaxhighlight> * '''ptr''':指向先前由malloc/calloc/realloc分配的内存块的指针 * '''size''':内存块的新大小(字节数) * '''返回值''':指向重新分配内存块的指针(可能与ptr不同) = 工作原理 = <mermaid> graph TD A[原内存指针ptr] --> B{size变化?} B -->|增大| C[尝试原地扩展] C --> D{连续空间足够?} D -->|是| E[直接扩展] D -->|否| F[分配新内存并迁移数据] B -->|缩小| G[可能释放尾部内存] B -->|size=0| H[等价于free] </mermaid> 关键行为说明: 1. '''原地扩展''':当原内存块'''后续的地址空间未被占用'''时,直接扩大分配 2. '''迁移扩展''':当无法原地扩展时,自动完成: * 分配新内存块 * 复制原数据(仅复制到min(旧大小,新大小)) * 释放原内存块 3. '''缩小内存''':可能释放多余内存,但实现依赖具体编译器 = 使用示例 = == 基础示例 == <syntaxhighlight lang="c"> #include <stdio.h> #include <stdlib.h> int main() { // 初始分配10个int的空间 int *arr = (int*)malloc(10 * sizeof(int)); // 检查分配是否成功 if(arr == NULL) { printf("内存分配失败!\n"); return 1; } // 使用内存(示例填充数据) for(int i=0; i<10; i++) arr[i] = i; // 需要更多空间,扩展到20个int int *new_arr = (int*)realloc(arr, 20 * sizeof(int)); if(new_arr == NULL) { printf("内存重新分配失败!\n"); free(arr); // 原始指针仍需释放 return 1; } arr = new_arr; // 更新指针 // 使用新增的空间 for(int i=10; i<20; i++) arr[i] = i; // 打印结果(部分示例) printf("扩展后数组[15]: %d\n", arr[15]); free(arr); // 最终释放 return 0; } </syntaxhighlight> '''输出示例''': <pre> 扩展后数组[15]: 15 </pre> == 错误处理模式 == 正确使用realloc应遵循以下模式: <syntaxhighlight lang="c"> void *tmp = realloc(ptr, new_size); if (tmp == NULL) { // 处理错误,原ptr仍然有效 // 可能需要执行清理操作 } else { ptr = tmp; // 只有成功时才覆盖原指针 } </syntaxhighlight> = 进阶注意事项 = == 性能考量 == realloc可能触发内存复制操作,时间复杂度为O(n)。对于大型内存块: * 频繁调整大小会导致性能下降 * 推荐策略:采用'''指数级增长'''(如每次扩大为原大小的1.5-2倍) 数学表达式: <math> new\_size = \lfloor old\_size \times \alpha \rfloor \quad (\alpha \in [1.5,2.0]) </math> == 特殊边界情况 == {| class="wikitable" ! 情况 !! 行为 !! 等效操作 |- | ptr为NULL || 等同于malloc(size) || malloc(size) |- | size为0 || 释放内存块 || free(ptr) |- | ptr未指向动态内存 || 未定义行为 || - |} = 实际应用案例 = == 动态数组实现 == 以下展示如何用realloc实现动态数组的自动扩容: <syntaxhighlight lang="c"> #include <stdio.h> #include <stdlib.h> typedef struct { int *data; size_t size; size_t capacity; } DynamicArray; void push_back(DynamicArray *da, int value) { if (da->size >= da->capacity) { // 容量不足时扩容(初始容量为1的情况) size_t new_capacity = da->capacity == 0 ? 1 : da->capacity * 2; int *new_data = realloc(da->data, new_capacity * sizeof(int)); if (!new_data) { printf("扩容失败!\n"); return; } da->data = new_data; da->capacity = new_capacity; } da->data[da->size++] = value; } </syntaxhighlight> == 内存池优化 == 在游戏开发等性能敏感场景中,可采用「预分配+realloc」策略: 1. 初始化时分配预估内存 2. 运行时根据实际需求精细调整 3. 避免频繁调用malloc/free = 常见问题 = {{Warning|1=错误示例:直接覆盖原指针}} <syntaxhighlight lang="c"> ptr = realloc(ptr, new_size); // 若失败会导致内存泄漏 </syntaxhighlight> {{Warning|1=错误示例:忽略返回值检查}} <syntaxhighlight lang="c"> realloc(ptr, new_size); // 未处理可能失败的情况 </syntaxhighlight> == 最佳实践总结 == * 总是检查返回值 * 使用临时指针接收结果 * 考虑内存对齐的影响(某些系统对realloc有特殊对齐要求) * 对于多线程环境,需要同步机制保护realloc操作 = 扩展阅读 = * 内存碎片化与realloc的关系 * 对比C++的vector.resize()实现 * 各标准库实现差异(glibc vs musl等) [[Category:编程语言]] [[Category:C]] [[Category:C 语言内存管理]]
摘要:
请注意,所有对代码酷的贡献均被视为依照知识共享署名-非商业性使用-相同方式共享发表(详情请见
代码酷:著作权
)。如果您不希望您的文字作品被随意编辑和分发传播,请不要在此提交。
您同时也向我们承诺,您提交的内容为您自己所创作,或是复制自公共领域或类似自由来源。
未经许可,请勿提交受著作权保护的作品!
取消
编辑帮助
(在新窗口中打开)
该页面使用的模板:
模板:Mbox
(
编辑
)
模板:Note
(
编辑
)
模板:Warning
(
编辑
)
模块:Arguments
(
编辑
)
模块:Message box
(
编辑
)
模块:Message box/ambox.css
(
编辑
)
模块:Message box/configuration
(
编辑
)
模块:Yesno
(
编辑
)