64 位 ELF 产生无法解释的结果

64-bit ELF yielding unexplainable results

有人可以解释为什么如果我在 64 位 中注释第一行 printf 或不注释,下面的代码在第二个 printf 上会产生不同的结果吗?

/* gcc -O0 -o test test.c */
#include <stdio.h>
#include <stdlib.h>

int main() {

    char a[20] = {0};
    char b = 'a';
    int count=-1;


    // printf("%.16llx %.16llx\n", a, &b);
    printf("%x\n", *(a+count));

return 0;
}

第二个 printf 得到以下结果:

提前致谢!

iansus

Can someone explain why the following code yields different results on the second printf if I comment the first printf line or not

您的程序使用 a[-1],因此表现出未定义的行为。 任何事情 都可能发生,弄清楚为什么会发生这样或那样的事情毫无意义

准确的原因是您正在读取第一个 printf(在注释时)写入的内存。

我得到了不同的结果(这是预期的未定义行为):

// with first `printf` commented out:
ffffffff

// with it commented in:
00007fffffffdd20 00007fffffffdd1b
ffffffff

您可以通过在其上设置 GDB 观察点来查看该内存写入的位置:

(gdb) p a[-1]
 = 0 '[=11=]0'
(gdb) p &a[-1]
 = 0x7fffffffdd1f ""
(gdb) watch *(int*)0x7fffffffdd1f
Hardware watchpoint 4: *(int*)0x7fffffffdd1f
(gdb) c
Continuing.
Hardware watchpoint 4: *(int*)0x7fffffffdd1f

Old value = 0
New value = 255
main () at t.c:12
12      printf("%.16llx %.16llx\n", a, &b);

在我上面的例子中,值是作为初始化 count=-1 的一部分写入的。也就是说,对于我的 gcc 版本,count 位于 a[0] 之前。但这可能取决于编译器版本,这个编译器是如何构建的,等等。