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

C语言中static关键字为何会改变数组越界后的程序行为?

静态关键字static在数组越界赋值场景下的行为差异解析

问题场景

尝试给int类型数组的范围外位置赋值时,出现了两种截然不同的行为:

  • 未加static时,程序直接崩溃,Shell返回1并终止;
  • 给数组和变量添加static后,越界赋值成功覆盖了后续变量,程序输出变量原本的值42。

代码示例1(无static)

#include <stdio.h>

int main(void)
{
    int a[4];
    int b;

    a[4] = 42;

    printf("%i\n", b);
}

运行结果:

1
zsh: abort    ./memory

代码示例2(加static)

#include <stdio.h>

int main(void)
{
    static int a[4];
    static int b;

    a[4] = 42;

    printf("%i\n", b);
}

运行结果:

42

原因解析

1. 无static的局部变量:存储在栈区

普通局部变量(未加static)会被分配在**栈(stack)**上:

  • 栈的增长方向是从高地址向低地址,编译器为防止栈溢出,通常会在栈帧中插入栈保护机制(比如“金丝雀”值)。当给a[4]赋值时,越界操作破坏了栈保护数据,触发系统的栈溢出检测,直接终止程序。
  • 就算没有栈保护,栈上变量的布局也会受编译器优化、内存对齐规则影响,a[4]的地址不一定刚好对应变量b的地址,甚至可能覆盖栈帧里的关键数据(比如函数返回地址),同样会导致程序崩溃或异常行为。

2. 加static的变量:存储在静态存储区

带static的变量会被分配在静态存储区(data segment):

  • 静态存储区的内存是在程序启动时就分配好的,主流编译器通常会按照变量的声明顺序连续排列这些静态变量(C标准不强制要求,但实际实现基本如此)。数组a有4个int元素,a[4]正好是数组末尾之后的第一个内存位置,也就是变量b的地址。所以给a[4]赋值42,实际上就是修改了b的值,最终printf输出42。

注意:数组越界赋值属于未定义行为,即使静态存储区的场景下“正常工作”,这也是编译器实现带来的巧合,绝对不能依赖这种行为编写代码。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 03:23:13