计数器 int 在不询问的情况下递增

Counter int is incremented without asking

本文关键字:情况下 int 计数器      更新时间:2023-10-16

请考虑以下代码:

#include <string.h>
#include <stdio.h>
int main(int argc, char *argv[]) {
  const char *task = "foo";
  int key = 0;
  int arr[] = {};
  if (!strcmp(task, "foo")) {
    key++;
  }
  arr[key] = 2;
  key++;
  printf("key: %dn", key);
}

key的最终值是 3 。应该是2.

如果我在第一次出现时将"foo"更改为"foo1",则key的最终值是 1 ,正如预期的那样。

如果我将arr[key] = 2更改为 arr[key] = 1 ,或删除该行,则key的最终值是 2 ,正如预期的那样。

这是为什么呢?

代码中有未定义的行为,因此任何事情都可能发生。

int arr[] = {};

是一个非标准大小的零大小数组。 由于它的大小为 0,因此访问任何元素并设置其值是未定义的行为。 由于我们现在有未定义的行为,因此不再有任何方法可以推理程序的工作原理。

当你这样做时:

int arr[] = {};您正在尝试告诉编译器为大小等于 {} 之间指定的元素的大小数组分配内存。但是由于您没有元素,编译器没有分配任何内存。所有这些都发生在编译时。

然后你试图arr[key] = 2;,你试图修改你不拥有的内存。在这种情况下,您要么会得到分段错误,要么代码会静默地继续移动并损坏分配的内存,这些内存由您的代码分配给其他地方。

所以理想情况下,你应该在{}之间有一些元素,如果你在编译时知道你永远不会需要更多,或者在运行时使用动态分配。

这是未定义的行为,因此它可能会在不同的编译器上或出于多种原因中的任何一种产生不同的结果。

您定义的数组长度为零。该标准可能会强制要求最小长度为 1,但在这种情况下,这并不重要 - 您正在访问[1]无论哪种方式都超出界限。这就是导致未定义行为的原因。

相关文章: