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

为何C语言越界访问内存时A代码正常B代码触发glibc断言失败?

为何内存越界的两段代码表现不同?一段正常运行一段触发glibc断言失败?

核心原因:未定义行为的不可预测性

两段代码都存在内存越界访问(分配了10个int的空间,却访问了第11个元素items[10]),这属于C语言中的未定义行为。未定义行为的特点是:程序运行结果完全不可预测,编译器、运行时环境的微小差异都可能导致截然不同的表现——可能正常运行、可能崩溃、可能破坏其他数据,甚至同一段代码多次运行结果都不一样。

两段代码表现差异的具体分析

代码A比代码B多了一行printf("allocated: %lu bytes\n", 10 * sizeof(int));,这行代码会触发以下影响:

  1. printf操作标准输出流stdout时,glibc的标准IO库会为输出流分配内部缓冲区,这个过程可能调用malloc分配内存,直接改变了堆的布局结构。
  2. 代码A中,堆布局因额外的malloc调用被改变,越界写入items[10]时,写入位置没有破坏glibc堆管理的关键元数据(比如堆块大小、空闲链表指针等),因此程序没有立刻触发可见错误。
  3. 代码B没有这行printf,堆布局更紧凑,越界写入items[10]直接覆盖了堆管理的元数据,触发了glibc在sysmalloc中的完整性断言检查,从而抛出致命错误。

关于GCC未报错的说明

内存越界属于运行时错误,GCC默认编译选项不会对这类数组下标越界进行强制检测(仅能识别部分编译期可明确判断的越界,比如常量下标访问栈上数组的情况)。若需要检测这类错误,可开启以下选项:

  • 编译时警告:-Warray-bounds,可检测部分编译期可识别的数组越界
  • 运行时检测:-fsanitize=address,借助AddressSanitizer工具,精准检测内存越界、使用已释放内存等问题

总结

  • 两段代码均为非法代码,不存在“代码A运行正常”的说法——它只是碰巧未触发可见错误,但已破坏内存完整性,后续可能引发更隐蔽的问题。
  • 未定义行为的表现完全不可控,不能依赖任何看似“正常”的运行结果。
  • 解决这类问题的根本方法是严格保证所有内存访问都在合法范围内,避免越界。

编译器错误信息:

Fatal glibc error: malloc assertion failure in sysmalloc: (old_top == initial_top (av) && old_size == 0) || ((unsigned long) (old_size) >= MINSIZE && prev_inuse (old_top) && ((unsigned long) old_end & (pagesize - 1)) == 0)

代码片段:

#include <stdio.h>
#include <stdlib.h>

int main()
{
#if 1
    // A
    int *items = malloc(10 * sizeof(int));
    printf("allocated: %lu bytes\n", 10 * sizeof(int));
    items = items;
    items[0] = 5;
    items[9] = 5;
    items[10] = 5;
    printf("[");
    for (size_t i = 0; i <= 10; i++)
    {
        printf(" %d", items[i]);
    }
    printf(" ]\n");
#else
    // B
    int *items = malloc(10 * sizeof(int));
    items = items;
    items[0] = 5;
    items[9] = 5;
    items[10] = 5;
    printf("[");
    for (size_t i = 0; i <= 10; i++)
    {
        printf(" %d", items[i]);
    }
    printf(" ]\n");
#endif
    return 0;
}

内容的提问来源于stack exchange,提问作者Caspian Power

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 17:05:13