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

C语言声明数组时的栈内存布局及数组索引存储顺序问题

C语言局部变量栈布局与数组存储顺序解答

注意:以下结论基于x86/x86_64、ARM等主流硬件架构,GCC、Clang、MSVC等主流编译器无优化、未开启栈保护(如Canary)的默认场景,C语言标准本身未对栈生长方向、局部变量分配顺序做强制规定,实际场景可能存在差异。

1. 基础规则说明

  • 主流架构的栈默认从高内存地址向低内存地址生长:函数进入时栈指针向低地址偏移预留局部变量空间,先声明的局部变量通常分配在更高的内存地址。
  • C语言数组的元素存储遵循下标越低、地址越低的规则:即任意数组arr,都满足&arr[0] < &arr[1] < ... < &arr[n-1]。

2. 第一段代码的栈布局

第一段代码:

int main()
{
    int a = 0;
    char b[8];
    char c[8];
}

从高地址到低地址的内存布局顺序和你理解的一致,依次为:

  • 4字节int变量a(最高地址)
  • 8字节char数组b:b[7]位于b的最高地址端,靠近a;b[0]位于b的最低地址端
  • 8字节char数组c(最低地址):c[7]位于c的最高地址端,靠近b;c[0]位于c的最低地址端
    如果对c做越界写,溢出的内容会先覆盖b数组,继续溢出会覆盖a变量。

3. 第二段代码的数组索引顺序问题

第二段代码(补全语法后):

int main()
{
    int a = 0;
    int b[8];
    char c[8];
}

从高地址到低地址的内存布局顺序和你猜测的一致:

  • 4字节int变量a(最高地址)
  • 32字节int数组b(8个元素每个占4字节)
  • 8字节char数组c(最低地址)

你关注的数组索引和a的距离问题:
因为数组元素地址随索引递增而升高,b[7]是b数组中地址最高的元素,b[7]的地址更靠近a的内存地址,b[0]是b数组中地址最低的元素,更靠近c的内存地址。
如果对c做越界写,溢出内容会先覆盖b[0],再依次覆盖b[1]到b[7],继续溢出才会覆盖a变量。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 01:18:01