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

C语言中char与int变量地址差值为16的原因是什么?

局部变量地址差为16的原因

首先明确最核心的规则:C语言标准从未规定函数内局部变量在栈上的排布顺序、相邻变量的间隔大小必须和代码声明顺序、变量自身大小严格绑定,你观测到的16字节差值是编译器遵循平台ABI规则做栈布局的正常结果,具体原因可以拆成三点:

  • 首先你观测到的地址本身就不符合"按声明顺序排布"的直觉:先声明的char a地址是0x7fffadfcc2c0,后声明的int b地址是0x7fffadfcc2b0,a的地址比b高16字节,这是因为进程栈默认从高地址向低地址增长,编译器完全可以调整变量的存放顺序,不会严格跟着你写代码的先后顺序挨着分配空间。
  • 其次16字节是x86_64平台的默认栈对齐要求:编译器分配栈空间时,会保证每个变量的地址满足自身的对齐规则(比如int要求4字节对齐),同时整个栈帧要满足16字节对齐的规范,变量之间的空隙要么是对齐填充用的,要么是预留给栈保护金丝雀值、临时隐式数据的空间,不会把两个变量毫无缝隙地挤在一起。
  • 你之前"地址间隔应该大于16"的推导逻辑本身是错的:32位int占4字节,8位char占1字节,两个变量本身总大小才5字节,就算加上对齐填充,最小的地址差可以小到4字节(int对齐到4字节边界时),16字节的差值完全在正常范围内,反倒是你提到的40这类差值才是少见情况,一般只有开了特殊编译选项、栈上额外存了很多其他数据时才会出现。

注意:永远不要写依赖局部变量地址差的业务代码。只要换编译器版本、调整优化等级、增减编译选项,局部变量的排布位置、间隔大小都会发生变化,没被使用的变量甚至会被编译器直接优化掉,根本不会分配栈地址。

复现用测试代码

int main(void)
{
    char a = 'g';
    int b = 5;
    printf("%p %p\n", &a, &b);

    return 0;
}

GDB地址差计算结果

(gdb) p 0x7fffadfcc2c0 (a) - 0x7fffadfcc2b0 (b)
$1 = 16

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 01:51:20