为什么 C 程序中的垃圾值有一个模式?

Why there is a pattern on the garbage values in the C program?

我在 CS50 第 4 周记忆中尝试了这个程序。我注意到垃圾值有一个模式。最初,我认为垃圾值应该是随机的。但是,看起来有不同的模式取决于请求的垃圾值的数量。

代码:

#include <stdio.h>
#include <stdlib.h>
int main (void)
{
    //Create an array of 3
    int scores[3];

    //Print 3 random garbage values
    //scores[0] have big random values
    //scores[1] have 3276X
    //scores[2] have 0
    for (int i = 0; i < 3; i++)
    {
        printf("%i\n", scores[i]);
    }
}

结果:

pset4/W4.1/ $ ./garbage
-1498813296
32767
0
pset4/W4.1/ $ ./garbage
-1011161520
32764
0
pset4/W4.1/ $ ./garbage
1340521040
32765
0
pset4/W4.1/ $ ./garbage
1244491248
32765
0
pset4/W4.1/ $ ./garbage
-1200874656
32764
0

谁能帮忙解释一下这是怎么回事?谢谢!

假设 x86_64,当你像这样声明一个数组时,编译器只是在堆栈上腾出空间,类似于:

sub , %rsp(3 个整数为 12 个字节)

然后,当您访问数组时,您实际上是在查看堆栈。我知道你有一个 64 位的 OS,因为如果你使用 scores[0] + scores[1] << 32,你会得到类似于 0x0000 7FFC 4A2D 6DF0 的东西,恰好堆栈从 0x0000 7FFF FFFF FFFF 开始并向下增长。所以你看到的是堆栈上的一个指针(可能是上一次调用的 return 地址)并且你知道堆栈上下一个值的底部 32 位是 0,可能是函数的局部变量, 谁知道呢

重要的是堆栈不会发生太大变化(尤其是高 32 位),这就是为什么您会注意到这种 32 764 (0x7FFC) 模式的原因。

阅读更多: https://en.wikipedia.org/wiki/X86_calling_conventions