【问题标题】:Calling main from another function从另一个函数调用 main
【发布时间】:2016-07-14 02:55:53
【问题描述】:

我是 C 新手,如果这个查询是基本的,请见谅。

我想从另一个函数调用 main(),让程序无限运行。代码在这里:

#include <stdio.h>

void message();

int main()
{
    message();

    return 0;
}

void message()
{
    printf("This is a test message. \n");

    main();
}

我希望看到这个程序无限运行。但是,它运行了一段时间,然后突然停止。使用我在测试消息旁边打印的计数器变量,我发现语句“这是一条测试消息”。打印了 174608 次,之后我收到一条错误消息

分段错误(核心转储)

然后程序终止。这个错误是什么意思?而程序为什么只运行了 174608 次(为什么不是无限次)?

【问题讨论】:

  • 你的机器有无限的内存吗?
  • 当一个方法被调用时,返回地址被放入栈中。当方法返回时,地址再次从堆栈中取出。但是您的方法永远不会返回,它们会轮流调用对方。因此,在 174608 次调用之后,您的堆栈已满。这个堆栈过低会导致您收到分段错误。没有更清晰的错误信息,因为堆栈溢出破坏了整个过程,使错误处理变得非常困难。
  • René 提供的答案是正确的,应该是一个答案,而不仅仅是评论。我只想补充一点,你永远不应该在你的程序中调用 main 函数。绝不。如果你想要无限循环,请使用 while(1) 或 for(;;)。
  • @詹姆斯邦德。你真的知道谁调用了你程序的 Main() 函数吗?你真的尝试过这段代码进行无限循环运行吗?
  • @RenéVogt 感谢您的精彩回答。我现在完全明白了。我不知道这个概念。我会永远记住这一点。

标签: c function main


【解决方案1】:

无限递归导致堆栈溢出。在main中进行无限循环:

int main()
{
  while (1)
  {
    //...
  }
}

【讨论】:

  • 嘿,这是网站的名称!
  • @Kupiakos 就是这样:)
【解决方案2】:

相互递归会消耗堆栈空间。如果将递归放入main() 本身,编译器可能识别尾递归,并通过迭代替换它。 [为了娱乐和教育,不要在家里尝试这个,孩子们 ...]:

#include <stdio.h>      

void message(); 

int main()
{
    message();  

    return main();
}       

void message()  
{       
    printf("This is a test message. \n");
}

GCC 可以识别优化级别=2 及以上的尾递归。 gcc -O2 -S main.c 的 main.s 输出:

        .p2align 4,,15
.globl main
        .type   main, @function
main:
        pushl   %ebp
        movl    %esp, %ebp
        andl    $-16, %esp
        .p2align 4,,7
        .p2align 3
.L4:
        call    message
        jmp     .L4
        .size   main, .-main
        .ident  "GCC: (Ubuntu 4.4.3-4ubuntu5.1) 4.4.3"
        .section        .note.GNU-stack,"",@progbits

【讨论】:

    【解决方案3】:

    这不等同于while(1) {...}for(;;) {...},它们会给你无限循环。

    每次调用函数(例如,main()message())时,都会将一些值压入 堆栈。当函数被调用太多次时,你的堆栈被填满,最后溢出,给你一个“堆栈溢出”错误。

    请注意,此错误与此站点无关,尽管它们恰好具有相同的名称:)

    【讨论】:

      猜你喜欢
      • 2010-12-19
      • 2021-08-19
      • 2011-10-07
      • 1970-01-01
      • 2017-09-27
      • 1970-01-01
      • 2012-11-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多