Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/visual-studio/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 为什么我在堆栈中启动的变量之间存在“间隙”?_C_Linux_Stack_X86 64_Buffer Overflow - Fatal编程技术网

C 为什么我在堆栈中启动的变量之间存在“间隙”?

C 为什么我在堆栈中启动的变量之间存在“间隙”?,c,linux,stack,x86-64,buffer-overflow,C,Linux,Stack,X86 64,Buffer Overflow,我正试图处理缓冲区溢出的问题 当程序计数器到达ifmodified!=0,则基指针为0x00007FFFFFFFE0 在基指针的正下方,我看到4个字节包含有意义的整数0 但是,缓冲区不在修改的int的正下方 看起来像是4个字节的0,然后0x00007fff在堆栈中,然后我输入的64个字节紧跟其后 为什么字符缓冲区[64]不在int修改之后出现?为什么会有差距 我用gcc-g-fno堆栈保护器test1.c-o test1编译了它 首先,您应该了解,编译器/链接器可以自由地将任何地址分配给您在“自

我正试图处理缓冲区溢出的问题

当程序计数器到达ifmodified!=0,则基指针为0x00007FFFFFFFE0

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

但是,缓冲区不在修改的int的正下方

看起来像是4个字节的0,然后0x00007fff在堆栈中,然后我输入的64个字节紧跟其后

为什么字符缓冲区[64]不在int修改之后出现?为什么会有差距

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


首先,您应该了解,编译器/链接器可以自由地将任何地址分配给您在“自动”范围内声明的变量,即函数的本地变量,而main实际上只是另一个函数


至于为什么会有4个字节的“零”-这几乎可以肯定,因为在您使用的平台上,编译器知道对内存的访问效率更高,即当该内存的地址与8个字节的值对齐时,访问速度更快-因此它会“添加”额外的4个字节以适当地“对齐”缓冲区数组的地址。有关对齐和效率的讨论,请参阅。

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

请参阅System V x86-64 psABI 1.0版的第15页链接


如果使数组大小小于16字节,则不会发生这种情况。但是,还有一个GCC错误,它意外地将此规则应用于所有大于16位(即2字节)的数组。GCC 7.1已经解决了这一问题。

您如何知道缓冲区从何处开始?因为计算机?如果没有一个非常具体的系统,讨论堆栈框架布局是没有意义的。大多数系统都有向下计数堆栈,但这并不一定相关。是的,linux x86_64 LinuxI在问题中添加了相关标记。
#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!");
}