首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >为什么我在堆栈中启动的变量之间存在“差距”?

为什么我在堆栈中启动的变量之间存在“差距”?
EN

Stack Overflow用户
提问于 2020-01-30 06:47:46
回答 2查看 233关注 0票数 0

代码语言:javascript
运行
AI代码解释
复制
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>

int main(int argc, char **argv) {
    int modified;
    char buffer[64];

    modified = 0;
    gets(buffer);

    if(modified != 0)
        printf("Changed!");
    else
        printf("Not changed!");
}

我在玩缓冲区溢出的游戏。

当程序计数器到达if(modified != 0)时,基本指针为0x00007fffffffdfe0。

在基本指针的正下方,我看到4个字节包含整数0,这是有意义的。

但是,缓冲区不在int修改之后。

它看起来像是4字节的0,然后0x00007fff在堆栈中,然后64字节,正如我随后输入的。

为什么char buffer64不在int修改之后出现呢?为什么会有“差距”?

我用gcc -g -fno-堆栈保护程序test1.c -o test1编译了它

谢谢

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-01-30 07:33:44

你已经有了一个大致的答案。特别是对于您的平台(GCC/Linux/x86_64),相关的ABI (SystemVx86-64)指定大小为16字节或更大的数组总是至少对齐16字节。正如@AdrianMole在他的回答中所指出的,这是为了提高性能,特别是允许在数组上使用SSE指令。

请参阅系统Vx86-64 psABI版本1.0链接这里的第15页。

如果使数组大小小于16字节,则不会发生这种情况。然而,也有一个GCC错误意外地将此规则应用于所有大于16位的数组,即2字节。GCC 7.1已经修正了这一点。

票数 3
EN

Stack Overflow用户

发布于 2020-01-30 07:00:47

首先,您应该理解编译器/链接器可以为您在“自动”作用域中声明的变量(即函数的本地变量--而main实际上是另一个函数)分配任意地址。

至于“为什么”存在‘0’的4个字节--这几乎可以肯定是因为,在您使用的平台上,编译器知道当内存的地址对齐到8字节值时,访问内存的效率更高(即更快)--因此它会添加‘额外的4个字节以适当地’对齐‘buffer数组的地址。有关对齐和效率的讨论,请参见这里

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59988585

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档