C GDB在运行时打印不同的值

C GDB在运行时打印不同的值,c,debugging,gdb,C,Debugging,Gdb,我是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; } 但是,对于gdb,行为看起来非常不同: $ gdb

我是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;
}
但是,对于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
$1 = {34, false}
(gdb) p arr[2]
$2 = 211
其中是
a.exe
给出的130的返回值?为什么是130?为什么是211?我完全不明白
$1={34,false}
。我使用
-g
标志编译。它的意思是:
gcc-g buggy.c

我的gcc版本编译器提供了以下内容:gcc(gcc)9.3.0

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

我的操作系统运行:Windows 7 Professional i686


处理:Cygwin安装程序版本2.905(32位)
arr
只有2个元素,访问
arr[2]
相当于访问数组的第三个元素,它不存在,这会调用未定义的行为,因此,此程序不会出现一致的行为

  • 未定义的行为
  • 使用不可移植或错误的程序结构或错误的数据时的行为,本国际标准对此不作要求

  • 可能的未定义行为包括:完全忽略情况并产生不可预测的结果,在翻译或程序执行过程中以环境特有的方式(无论是否发出诊断消息)进行行为,以及终止翻译或执行(发出诊断信息)


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

    arr
    只有2个元素,访问
    arr[2]
    相当于访问数组的第三个元素,该元素不存在,这将调用未定义的行为,因此,此程序不需要一致的行为

  • 未定义的行为
  • 使用不可移植或错误的程序结构或错误的数据时的行为,本国际标准对此不作要求

  • 可能的未定义行为包括:完全忽略情况并产生不可预测的结果,在翻译或程序执行过程中以环境特有的方式(无论是否发出诊断消息)进行行为,以及终止翻译或执行(发出诊断信息)


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

    C++在该语言中没有任何数组绑定检查(1),因此,如果对数组的末尾进行索引,则会得到未定义的行为,这意味着编译器可以自由地执行任何它认为方便的操作

    在实践中,这意味着它将访问如果数组更大时会使用的任何内存,将超过为数组分配的内存的一个运行到已经用于其他内容的内存中

    您没有在程序的内存中设置任何值,因此它将返回内存中恰好存在的任何值

    当您在调试器下运行时,您会在内存中移动内容,而计算机的运行方式略有不同,因此没有理由期望该值与正常运行时的值相同。无论如何,每次运行程序时,该值都可能不同


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

    C++在语言中没有任何数组绑定检查(1),因此,如果对数组的末尾进行索引,则会得到未定义的行为,这意味着编译器可以自由地执行任何它认为方便的操作

    在实践中,这意味着它将访问如果数组更大时会使用的任何内存,将超过为数组分配的内存的一个运行到已经用于其他内容的内存中

    您没有在程序的内存中设置任何值,因此它将返回内存中恰好存在的任何值

    当您在调试器下运行时,您会在内存中移动内容,而计算机的运行方式略有不同,因此没有理由期望该值与正常运行时的值相同。无论如何,每次运行程序时,该值都可能不同


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

    当遇到断点并且gdb向您显示一行代码时,程序在该行代码执行之前已停止。因此在第5行,
    bool arr[2]={true,false}
    ,尚未将这些值分配给数组。当遇到断点并且gdb向您显示一行代码时,程序已在该行代码执行之前停止。因此,在第5行,
    bool arr[2]={true,false};
    ,尚未将这些值分配给数组。
    $ 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
    $1 = {34, false}
    (gdb) p arr[2]
    $2 = 211