Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/62.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_Arrays_Undefined Behavior - Fatal编程技术网

索引超过C数组末尾

索引超过C数组末尾,c,arrays,undefined-behavior,C,Arrays,Undefined Behavior,我用C编写了一个简短的程序,只是想看看当索引超过数组末尾时会发生什么 我发现它主要产生随机值(我知道它们实际上不是随机的),直到一个点(在本例中,52个索引超过末尾),在这个点上它每次产生0。每一个值超过这一点,程序就会崩溃。为什么会这样?程序分配的内存空间是否已结束 main() { int ar[4]; ar[0] = 99; ar[1] = 45; printf("array: %d, %d random value: %d", ar[0], ar[1]

我用C编写了一个简短的程序,只是想看看当索引超过数组末尾时会发生什么

我发现它主要产生随机值(我知道它们实际上不是随机的),直到一个点(在本例中,52个索引超过末尾),在这个点上它每次产生0。每一个值超过这一点,程序就会崩溃。为什么会这样?程序分配的内存空间是否已结束

main()
{
    int ar[4];
    ar[0] = 99;
    ar[1] = 45;
    printf("array: %d, %d   random value: %d", ar[0], ar[1], ar[55]);
}
Edit:我还发现,如果我修改这个值,结果总是为0(即ar[55]=1000),那么程序的返回码就会上升

。。。只是想看看当索引超过数组末尾时会发生什么

尝试访问超出绑定的内存时,调用。任何事情都有可能发生,任何事情都有可能发生

在您的情况下,由于某种原因,可以从进程访问索引52之前的内存地址,因此它允许访问。将超过52个点的索引指向未分配给进程地址空间的内存区域,从而引发导致SEGFULT的访问冲突。这根本不是一种确定性行为,而且您无法依赖调用UB的程序的输出

。。。只是想看看当索引超过数组末尾时会发生什么

尝试访问超出绑定的内存时,调用。任何事情都有可能发生,任何事情都有可能发生


在您的情况下,由于某种原因,可以从进程访问索引52之前的内存地址,因此它允许访问。将超过52个点的索引指向未分配给进程地址空间的内存区域,从而引发导致SEGFULT的访问冲突。这根本不是一种确定性行为,您无法依赖调用UB的程序的输出。

访问数组边界以外的数组元素(在
0
之前或从其大小开始)是未定义的行为。它可能产生值,也可能不产生值,它可能导致程序突然结束,它可能导致系统停止、重新启动或起火

现代系统试图通过内存保护、用户空间限制等将未定义的行为限制在合理的范围内,但即使是用户空间代码错误也可能造成可怕的后果:

  • 起搏器干扰其计时值可导致过早死亡
  • 溢出数组边界的银行软件可能会覆盖帐户余额信息,并将不计其数的美元存入某个随机帐户
  • 你的自动驾驶汽车可能比酒后驾车的人表现更糟
  • 想想核电站控制软件、飞机仪表、军事设备
毫无疑问,应该避免未定义的行为

关于退出状态,您的程序对
main()
的定义使用了过时的语法,隐式返回类型在C99和更高版本中不再受支持,但不返回任何内容,这意味着其返回值可以是任意随机值,包括每次执行的不同值。C99为
main()
函数指定了一个kludge,并强制隐式
返回0
位于
main()
的末尾,但依赖它是不好的风格

类似地,在没有适当原型的情况下调用
printf()。在定义函数
main()
之前,应该包含

最后,
ar[0]
ar[1]
main()
中初始化,但是
ar[2]
ar[3]
没有初始化。请注意,访问未初始化的值也有未定义的行为。这些值可以是任何值,您将其描述为随机值,但在某些系统上,它们可能是陷阱值,仅通过读取它们就会导致未定义的行为


一些非常方便的工具可用于跟踪简单和复杂程序中的此类问题,最显著的是
valgrind
。如果您对这个主题感兴趣,一定要看看。

访问数组边界以外的数组元素(在
0之前或从其大小开始)是未定义的行为。它可能产生值,也可能不产生值,它可能导致程序突然结束,它可能导致系统停止、重新启动或起火

现代系统试图通过内存保护、用户空间限制等将未定义的行为限制在合理的范围内,但即使是用户空间代码错误也可能造成可怕的后果:

  • 起搏器干扰其计时值可导致过早死亡
  • 溢出数组边界的银行软件可能会覆盖帐户余额信息,并将不计其数的美元存入某个随机帐户
  • 你的自动驾驶汽车可能比酒后驾车的人表现更糟
  • 想想核电站控制软件、飞机仪表、军事设备
毫无疑问,应该避免未定义的行为

关于退出状态,您的程序对
main()
的定义使用了过时的语法,隐式返回类型在C99和更高版本中不再受支持,但不返回任何内容,这意味着其返回值可以是任意随机值,包括每次执行的不同值。C99为
main()
函数指定了一个kludge,并强制隐式
返回0
位于
main()
的末尾,但依赖它是不好的风格

类似地,在没有适当原型的情况下调用
printf()。在定义函数
main()
之前,应该包含

最后,
ar[0]
ar[1]
main()
中初始化,但是
ar[2]
ar[3]
没有初始化。请注意,访问未初始化的值也有未定义的行为。这些值可以是任何值,您将其描述为随机值,但在某些系统上,它们可能是陷阱值,仅通过读取它们就会导致未定义的行为

有些人是汉人