You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 04:58:12