C语言中Realloc未缩小内存?该行为是否正常?
关于realloc缩小内存后仍能访问原内存的问题
问题代码
#include <stdio.h> #include <stdlib.h> int main() { int size; int *a, *a2; size = 5; a = malloc(size * sizeof(int)); if(a == NULL) { fprintf(stderr, "Failure at allocating memory for array.\n"); abort(); } for(int i = 0; i < size; i++) { a[i] = i * i; printf("Array %d element: %d.\n", i, a[i]); } size = 2; a2 = realloc(a, size * sizeof(int)); if(a2 == NULL) { free(a); fprintf(stderr, "Failure at reallocating memory for array.\n"); abort(); } printf("\n"); size = 5; for(int i = 0; i < size; i++) { a2[i] = i * i * i; printf("Array %d element after realloc: %d.\n", i, a2[i]); } free(a2); return 0; }
运行输出
Array 0 element: 0. Array 1 element: 1. Array 2 element: 4. Array 3 element: 9. Array 4 element: 16. Array 0 element after realloc: 0. Array 1 element after realloc: 1. Array 2 element after realloc: 8. Array 3 element after realloc: 27. Array 4 element after realloc: 64.
用户疑问
调用realloc后并未将数组实际缩小到2个元素,反而仍能正常访问最初分配的全部5个元素,请问该行为是否正常?我是否存在代码错误?
回答
这个行为不属于正常可依赖的情况,你的代码存在明确错误:
- 当你用
realloc(a, 2 * sizeof(int))把内存缩小到2个int的大小后,原内存中索引≥2的部分已经被内存管理器标记为“不再属于当前程序”,后续访问这部分内存属于数组越界访问,这是C语言中的未定义行为。 - 之所以看起来能正常运行甚至输出正确值,只是因为内存管理器不会立刻清空或回收这部分内存——旧数据暂时还在,且没有被其他程序或当前程序的其他部分覆盖,但这完全是偶然的。换个操作系统、编译器版本,或者程序稍微修改,就可能出现崩溃、数据乱码、甚至破坏其他变量的严重问题。
- 代码的核心错误:realloc之后,你必须严格遵守新的内存大小,不能再访问超出新范围的内存区域。修正后的代码应该把realloc后的循环上限改为2,而不是改回5。
内容的提问来源于stack exchange,提问作者Agent 47
相关产品推荐
相关产品推荐

