GDB 在 运行 时打印不同的值

GDB prints different values while running

我是 gdb 的新手,我不明白赋予输出的值。我一直在测试一些玩具程序只是为了了解行为。

#include <stdbool.h>
#include <stdio.h>

int main(){
    bool arr[2] = {true, false};
    printf("Value at index 2 of array is %d\n", arr[2]);
    return 0;
}

正如我们所观察到的,有问题的程序的诀窍在于 arr[2],我们可以期待一些 NULL。但是当我编译它时给出:

$ ./a.exe
Value at index 2 of array is 130

然而,对于 gdb,行为看起来很不一样:

$ gdb a.exe
(gdb) b main
(gdb) run

Thread 1 "a" hit Breakpoint 1, main () at table.c:5
5           bool arr[2] = {true, false};
(gdb) p arr
 = {34, false}
(gdb) p arr[2]
 = 211

a.exe给出的130的返回值在哪里?为什么是130?为什么是211?而且我完全没看懂 = {34, false}。我用 -g 标志编译。意思是:gcc -g buggy.c

我的 gcc 版本编译器给出了这个:gcc (GCC) 9.3.0

GDB 版本:GNU gdb (GDB) (Cygwin 9.2-1) 9.2

我的 OS 运行:Windows 7 Professional i686

正在处理:Cygwin 安装程序版本 2.905(32 位)

arr 只有 2 个元素,访问 arr[2] 相当于访问数组的第三个元素,它不存在,这会调用未定义的行为,因此,没有一致的行为是期待这个节目。

ISO/IEC 9899:201x - §3.4.3

  1. undefined behavior

Behavior, upon use of a nonportable or erroneous program construct or of erroneous data,for which this International Standard imposes no requirements.

  1. NOTE

Possible undefined behavior ranges from ignoring the situation completely with unpredictable results, to behaving during translation or program execution in a documented manner characteristic of the environment (with or without the issuance of a diagnostic message), to terminating a translation or execution (with the issuance of a diagnostic message).

= {34, false} 可能是您在数组初始化之前打印数组的结果,在下一行设置断点应该会给您正确的结果。

C++ 在语言 (1) 中没有任何数组绑定检查,所以如果你索引数组的末尾,你会得到未定义的行为,这意味着编译器可以自由地做任何它认为方便的事情。

在实践中,这意味着如果数组更大,它将访问任何本应使用的内存,运行将分配给数组的内存分配到已经用于其他用途的内存中。

您没有在程序中为该内存设置任何值,因此它将 return 恰好在该内存中的任何值。

当您 运行 在调试器下移动内存和计算机中的东西时 运行 的东西有点不同,因此没有理由期望值与正常运行。无论如何,每次 运行 程序可能会有所不同!

(1) 一些库函数如 vector::at 有边界检查,一些编译器将它作为扩展提供,但核心语言没有定义任何。