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

缓冲区溢出(Buffer Overflow):为何缓冲区赋值会影响其他变量?

为什么越界写入buf[4]会导致value变成1?

先看你的代码:

void foo() {
    int value = 0;
    char buf[4];
    buf[4] = 1;

    printf("value: %d\n", value);
}

int main() {
    foo();
    return 0;
}

核心原因是栈帧内存布局+缓冲区溢出,小端序是让最终结果符合预期的关键细节,拆解如下:

  • 函数栈的变量排列规则
    当调用foo()时,编译器会为它分配一段栈内存(栈帧)存储局部变量。在GCC等多数编译器的默认编译规则下,先声明的局部变量会被放在栈的高地址区域,后声明的变量放在低地址侧。也就是说:
    • value先声明,占4字节(int的常见长度),处于栈的高地址段
    • buf[4]后声明,占4字节(4个char),紧挨着value的低地址方向

举个便于理解的地址示例:假设value的起始地址是0x1004,那么buf的四个元素地址依次是0x1000、0x1001、0x1002、0x1003。此时buf[4]对应的地址就是0x1004——正好是value的第一个字节地址。

  • 缓冲区溢出的本质
    buf的合法索引范围是0到3,buf[4]属于越界访问。你给它赋值1,本质是把数据写入了不属于buf的内存区域,而这块区域恰好是value的内存空间。

  • 小端序的作用
    当前系统采用小端字节序,意味着多字节数据的低字节存储在内存低地址,高字节存储在内存高地址。value是4字节int类型,初始值为0时四个字节全为0。当你往它的低地址(第一个字节)写入1后,这块4字节内存的数据就变成了0x01 0x00 0x00 0x00。按照小端序解析,这个值对应十进制的1,所以printf输出的value就是1。

⚠️ 注意:这种结果是依赖特定编译环境的未定义行为——如果更换编译器、修改编译选项(比如开启栈保护)、切换操作系统,栈布局可能完全不同,越界写入不一定会修改value,甚至可能直接导致程序崩溃。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 15:22:55