8
int data[8];
data[9] = 1;

C++ 标准对此有何评论?这是未定义的行为吗?

至少 C 编译器 (gcc -std=c99 -pedantic -W -Wall) 没有说明任何内容。

4

7 回答 7

8
于 2013-09-10T19:23:00.133 回答
4

是的,这是未定义的行为。

即使编译器能够检测到未定义的行为,它也可能会或可能不会警告您。

于 2013-09-10T19:12:25.797 回答
4

这被认为是未定义的行为。如果您尝试编译将导致未定义行为的代码,编译器不需要发出警告,尽管这样做很好。

于 2013-09-10T19:12:45.393 回答
2

不明确的。它可能是也可能不是无效的内存,这使得它很危险。你可以使用像 valgrind 这样的工具来检测这样的错误访问。

于 2013-09-10T19:12:32.383 回答
2

是的,这是未定义的行为。一切都可能发生,它可能工作或不工作,它可能工作 2 年然后停止工作。这是三个中最危险的:

  • 未定义的行为
  • 未指明的行为
  • 实现定义的行为

您可能会检查它以与其他亲戚见面: C++ 程序员应该知道的所有常见未定义行为是什么?

未定义、未指定和实现定义的行为

于 2013-09-10T19:18:04.160 回答
2

C 和 C++ 不检查边界。您试图达到的价值几乎可以是任何东西。它似乎可以在您的编译器上运行,但它不是合法的 C 或 C++,并且不能保证它在您下次运行程序时仍然可以运行。

根据 ISO C 标准,访问边界外的数组会导致

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

当您尝试取消引用指向您的程序不允许访问的内存的指针时,会发生分段错误,并且只是越过数组的末尾可能不会导致这种情况。但它很可能会给你一些不好的价值。

于 2013-09-10T19:18:24.937 回答
1

是的,这是未定义的行为,一些编译器会对此发出警告,而其他编译器则不会,但让我们看一下,您的代码会发出警告。

查看运营商的[]内联实现。a[b]实际上是*(a + b)。所以回到你的代码。

int data[8];
data[9] = 1;

首先,您分配堆栈的一部分并创建指向第一个元素的指针。然后你重写一些数据,它就在你的数组之后,所以你破坏了一些数据。

让我们再举一个例子:

int data[8];
int data2[8] = {};
data[9] = 1;

编译器很可能会生成分配一次并创建两个指针作为数组的代码。因此data[9] = 1;可以将第二个值设置data2为 1,但不能保证这一点。

于 2013-09-14T15:12:44.520 回答