你的问题非常好,让我来详细解释:
问题1:内存泄漏问题
不会发生内存泄漏,原因如下:
// 原始分配
int* arr = (int*)malloc(3*sizeof(int)); // arr指向地址A
// realloc重新分配
int* new_arr = (int*)realloc(arr, 5*sizeof(int)); // new_arr可能指向地址B
arr = new_arr; // arr现在也指向地址B
关键点:
realloc()
函数会自动处理旧内存的释放- 如果
realloc
成功且返回了新地址,系统会自动释放原来的内存块 - 你不需要(也不应该)手动释放原来的内存
问题2:为什么不free(new_arr)
free(arr); // 这里实际上就是释放了new_arr指向的内存
arr = NULL;
因为arr
和new_arr
指向的是同一块内存,所以只需要释放一次。
realloc的三种可能情况:
- 原地扩展:如果原内存块后面有足够空间,直接扩展,返回相同地址
- 异地迁移:如果后面空间不够,申请新的大内存块,拷贝数据,自动释放旧内存
- 失败返回NULL:申请失败,原内存块保持不变
改进的代码写法:
#include <stdio.h>
#include <stdlib.h>
int main() {
int* arr = malloc(3 * sizeof(int));
if(arr == NULL) return 1;
arr[0] = 1; arr[1] = 2; arr[2] = 3;
printf("Original array: ");
for(int i = 0; i < 3; i++) printf("%d ", arr[i]);
printf("\n");
// realloc扩展内存
int* temp = realloc(arr, 5 * sizeof(int));
if(temp == NULL) {
printf("Reallocation failed! Keeping old block.\n");
free(arr); // ⚠️这里需要释放的是原arr
return 1;
}
arr = temp; // ✅更新指针
// 使用扩展后的数组
arr[3] = 4;
arr[4] = 5;
printf("After realloc: ");
for(int i = 0; i < 5; i++) printf("%d ", arr[i]);
free(arr); // ✅只需释放一次
return 0;
}
总结:realloc()
的设计很智能,它会自动管理新旧内存的转换,避免了手动拷贝数据和双重释放的问题。
内容由零声教学AI助手提供,问题来源于学员提问