C语言实现动态数组翻倍扩容时出现realloc错误如何修复
问题原因
- 扩容触发时机错误:数组下标从0开始计数,长度为
*size的数组合法下标范围是0 ~ *size-1。你的判断条件写的是if (i > *size),意味着当i等于*size时已经在访问越界内存,写入操作会破坏堆内存的元数据,这就是realloc: invalid next size报错的根因。 - 循环变量重名(非致命但不规范):外层循环变量是
i,扩容后打印数组的内层循环又定义了同名的i,虽然C支持块级作用域不会直接报错,但容易引发逻辑混淆。 - 缺少必要头文件、无内存分配失败校验,也会导致程序稳定性差。
修复代码
修改扩容判断条件为i >= *size,同时补充必要的安全校验,修复后的完整代码如下:
#include <stdio.h> #include <stdlib.h> int* doubleArray(int* vect, int* dim) { int old_dim = *dim; int new_dim = old_dim * 2; // realloc安全写法,避免分配失败丢失原指针 int* temp = realloc(vect, new_dim * sizeof(int)); if (temp == NULL) { perror("realloc failed"); exit(EXIT_FAILURE); } vect = temp; for (int i = old_dim; i < new_dim; i++) { vect[i] = 0; } *dim = new_dim; return vect; } int main() { int n = 3; int* arr = malloc(n * sizeof(int)); if (arr == NULL) { perror("malloc failed"); return EXIT_FAILURE; } for (int i = 0; i < 2048; i++) { // 修复扩容判断逻辑:下标等于数组长度时就触发扩容 if (i >= n) { int j = 0; arr = doubleArray(arr, &n); // 内部循环改用k作为变量名避免重名 for (int k = 0; k < n; k++) { j++; printf("%d ", arr[k]); } printf("\n%d\n\n", j); } arr[i] = rand() % 6; } // 释放堆内存避免泄漏 free(arr); return EXIT_SUCCESS; }
补充说明
原来只有初始大小满足2048 % value == 0时能正常运行,是因为这种场景下数组扩容刚好能在你写越界之前触发堆内存的页边界保护,侥幸没有破坏堆元数据,本质是未定义行为的巧合表现,不是正确逻辑。
内容的提问来源于stack exchange,提问作者PwNzDust
相关产品推荐
相关产品推荐

