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

为何改变局部变量初始化顺序后auth_flag地址未变?

为什么调整局部变量声明顺序后,变量地址始终不变?

我读了《Hacking: the Art of the Exploit》这本书,里面的例子表明:当int类型变量auth_flag在char数组buffer_password[16]之前声明时,auth_flag的地址会高于buffer_password;如果把auth_flag放在数组之后声明,它的地址应该低于buffer_password。但我实际测试时,不管怎么调整这两个变量的声明顺序,auth_flag的地址都没变,这是为什么?

测试代码如下:

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

int check_authentication(char *password) {
    char buffer_password[16];
    int auth_flag = 0;
    
    strcpy(buffer_password, password);
    
    if (strcmp(buffer_password, "brilling") == 0)
        auth_flag = 1;
    if (strcmp(buffer_password, "outgrabe") == 0)
        auth_flag = 1;
        
    return auth_flag;
}

原因分析:

  • 编译器内存布局优化:现代编译器(如GCC、Clang)会对栈上的局部变量做优化,不会严格遵循代码里的声明顺序分配空间。为了提升内存访问效率,编译器会把对齐要求相同、大小匹配的变量归置在一起,甚至调整位置减少内存碎片,所以你改声明顺序后,auth_flag可能还是被放到了优化后的固定位置。
  • 内存对齐规则:平台的内存对齐要求会约束变量位置。int类型一般要求4字节对齐,而buffer_password[16]本身是16字节(天然满足对齐),编译器可能为了符合对齐规则,固定把int变量放在某个对齐后的地址上,不受声明顺序影响。
  • 编译选项的差异:书中的例子大概率是基于旧版本编译器或关闭优化的编译环境。你可以尝试用-O0(完全关闭优化)选项编译代码,再观察变量地址是否会随声明顺序变化——很多时候开启优化后,编译器会彻底打乱局部变量的声明顺序。
  • 栈帧结构限制:函数的栈帧里除了局部变量,还有返回地址、栈基址(EBP/RBP)等固定结构。编译器会把局部变量统一分配在栈帧的特定区域,不会因为单个变量的声明顺序轻易改变整个栈帧的布局。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 01:33:27