realloc 是C标准库中用于动态内存重新分配的函数,定义在 <stdlib.h> 头文件中。它用于调整之前分配的内存块的大小。
函数原型
void *realloc(void *ptr, size_t size);
参数说明
- ptr:指向先前由
malloc、calloc或realloc分配的内存块的指针 - size:新的内存块大小(以字节为单位)
返回值
- 成功:返回指向重新分配的内存块的指针
- 失败:返回
NULL,且原内存块保持不变
功能描述
realloc 的行为取决于参数:
- 当
ptr为NULL时:
-
- 等同于
malloc(size) - 分配一块新内存
- 等同于
- 当
size为0且ptr不为NULL时:
-
- 等同于
free(ptr) - 释放原内存块
- 返回
NULL
- 等同于
- 常规情况(
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); // 错误!不检查是否成功
最佳实践
- 总是检查
realloc的返回值 - 使用临时变量保存结果,成功后再更新原指针
- 对于需要频繁调整大小的数据结构,考虑更高效的内存管理策略
- 释放内存时,将指针设为
NULL避免悬垂指针
2059

被折叠的 条评论
为什么被折叠?



