【问题标题】:Why this program compiled successfully but failed to run?为什么这个程序编译成功但运行失败?
【发布时间】:2017-08-02 16:15:29
【问题描述】:
#include <stdio.h>
main()
{
int i=5;
    if(--i)
    {
        main();
        printf("%d ",i);
    }

请注意,如果我们将int i 设为static,那么答案将是0000

【问题讨论】:

  • 什么是你不明白的?递归还是静态变量?
  • 通过添加静态我得到0000,这是可以理解的,但问题在循环中,终止条件不存在,现在我明白了。
  • 您可以在这里查看我的回答,了解当我们进行无限递归调用时会发生什么:stackoverflow.com/questions/45427160/…
  • 类似于this questionthis question
  • 编译成功然后运行失败是正常现象。

标签: c loops


【解决方案1】:

每次输入函数main() 时,变量i 的值5(每次调用main() 在堆栈上都拥有该变量的自己的副本)。没有递归终止,因为递归终止的条件永远不会满足(即:--i 永远不会计算为零)。 因此,main() 会被递归调用,直到堆栈上没有更多位置为止。

但是,如果您将i 声明为static,则对于对main() 的所有调用,都会有一个变量i 的共享副本。当--i 求值为零时满足递归终止条件。

【讨论】:

    【解决方案2】:

    它用完了空间(在堆栈上),因为它正在无限期地调用 main()

    【讨论】:

      【解决方案3】:

      代码本身是正确的,程序将编译没有任何问题。问题是条件if (--i) 将始终评估为真,因为每次递归调用main 时,都会创建一个新的本地i 变量,它总是值得5。随着您堆叠越来越多的调用,当堆栈不再增长时,程序将由 SIGSEGV 终止。你可以用 Valgrind 观察到这一点:

      ==10972== Memcheck, a memory error detector
      ==10972== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
      ==10972== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
      ==10972== Command: ./a.out
      ==10972==
      ==10972== Stack overflow in thread #1: can't grow stack to 0xffe801000
      ==10972==
      ==10972== Process terminating with default action of signal 11 (SIGSEGV)
      

      当您将i 声明为static 变量时程序输出0000 的原因是因为i 不会在每次main 调用时重新声明。所以基本上main 被递归调用,直到i 值得0。然后,所有堆叠的printfs 都被执行,但由于i 在每个堆叠调用中都值得0,您将看到0000static 关键字使所有 main 调用实际上引用同一个 i 变量而不是副本。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-03-09
        • 2015-05-29
        • 1970-01-01
        • 2018-12-05
        • 2010-09-20
        相关资源
        最近更新 更多