【问题标题】:Why an uninitialized variable in C still produces output为什么 C 中未初始化的变量仍会产生输出
【发布时间】:2012-11-19 22:58:44
【问题描述】:

我试图弄清楚为什么即使局部变量 i 从未在这个 C 程序中初始化,许多系统仍会打印出 0 1 2 3 4 5 6 7 8 9 有人可以解释这是为什么吗?任何帮助表示赞赏!

void foo() {
   int i;
   printf("%d ", i++);
}
int main() {
    int j;
    for (j = 1; j <= 10; j++) foo();
}

【问题讨论】:

  • 在我的系统上,它给出了134513713 134513714 134513715 134513716 134513717 134513718 134513719 134513720 134513721 134513722。所以,它可能会也可能不会是 0 1 2 等等。
  • 每个答案都将其归因于运气。你一定是个很幸运的人:)
  • 是的,我开始明白这一点,也许我只是认识合适的人 :)
  • 我手工制作的 C++ 编译器擦除了我的硬盘 10 次。它认为我的编译器按照标准做得很好!

标签: c variables stack initialization


【解决方案1】:

行为未定义。统计数据无关紧要。这可能是因为布局和堆栈的初始化,但也可能是其他任何原因。

例如,假设:

  1. 不检查变量是否已初始化。
  2. 这是一个简单的堆栈机。
  3. 堆栈初始化为 0。
  4. 变量i 分配在堆栈上,而不是作为寄存器。
  5. 调用函数时,不会初始化堆栈。

在这种情况下,i 每次都会引用堆栈上的同一个位置,将从 0 开始,并且堆栈上的同一个位置将每次加一。

【讨论】:

  • 谢谢,这很有意义并且很有帮助
【解决方案2】:

变量i 是在堆栈上创建的,但您没有对其进行初始化。所以它包含一些你无法预测的垃圾值。幸运的是,在您的情况下,该垃圾值最初为 0。如果在另一个系统上运行,您将获得一组不同的值。行为肯定是未定义的。

由于您除了在 for 循环中调用该函数之外什么都不做,幸运的是,该变量 i 每次都会被销毁并重新分配相同的内存空间。因此,它在迭代中也能保持其价值。

在我的系统上,它给出了这些值。

2009288233
2009288234
2009288235
2009288236
2009288237
2009288238
2009288239
2009288240
2009288241
2009288242

【讨论】:

    【解决方案3】:

    这可能是因为函数中的局部变量被重复地从同一个内存块中分配和释放。这就是输出重复递增的原因。

    初始值为零是运气。它可能是任何其他垃圾值。

    该行为未定义,无法在其他系统上运行。

    【讨论】:

      【解决方案4】:

      由于这是一个简单的程序,你很幸运 i 使用了相同的内存位置。由于它没有被初始化,它会选择之前的值。

      但是,这是未定义的。应该用警告编译它来发现这个错误。

      【讨论】:

        【解决方案5】:

        正如其他人所指出的,这是未定义的行为,因此没有可靠的答案。

        也就是说,您可能是对的,您获得的最常见的值是 0 到 9。这是因为操作系统在您的程序收到堆栈占用的内存之前将其清零。 foo() 代表已进行的最深调用,因此它使用的是操作系统将其归零后尚未触及的内存,因此在第一次调用时,它很可能仍包含零。

        在每个后续调用中,它可能占据堆栈上的相同位置,因此在每个后续调用开始时,它很可能以它在上一次调用结束时的值开始。

        尽管它是未定义的行为,但这一点都不能保证,但是是的,它可能至少比没有的可能性更大。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2016-12-28
          • 1970-01-01
          • 1970-01-01
          • 2022-12-02
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多