当main()调用main()时堆栈帧会发生什么

时间:2012-10-23 07:37:33

标签: c main stackframe

请考虑以下代码:

#include <stdio.h>

int main()
{
    static int counter=5;

    printf ("Counter = %d\n", counter);

    if (counter--)
    {
        main();
    }

    return 0;
}

编译:

gcc test.c -ansi -Wall –pedantic

执行:

[root@mars home]# ./a.out 
Counter = 5
Counter = 4
Counter = 3
Counter = 2
Counter = 1
Counter = 0

这里main()调用自己()。

每次main()被调用时,main()函数的原始堆栈框架都会被覆盖。

但回信地址是什么?函数可以返回自己的堆栈框架吗?

请帮我澄清这个疑问。

感谢。

3 个答案:

答案 0 :(得分:6)

不会被覆盖。这是一个正常的函数调用(在这种情况下是递归的)。您可能会对counter变量感到困惑。此变量声明为静态,这意味着仅初始化,因此下面的行仅“执行”一次:

static int counter=5;

换句话说,您可以将counter视为仅仅初始化一次的全局变量(值为5)。在main的每个调用中,它递减直到它达到零。在那之后,所有main函数都会返回,因此堆栈为unwinded(与正常函数调用一样)。

答案 1 :(得分:3)

在许多计算机语言中这是很正常的,称为“递归”。为每次调用函数创建一个新的堆栈帧,因此不会覆盖。

外部main()的返回地址与往常一样是运行时库。内部main()的返回地址是外部main()。

在你的例子中混淆水域的一件事是你宣称反击是静态的。这意味着它在数据段中的堆上而不是在堆栈上分配(如注释中的alk所解释的),因此每次调用main()都会共享相同的counter实例。

答案 2 :(得分:1)

简短回答:这是一个简单的递归案例。所以它将分配新的堆栈帧和不会覆盖前一帧。

答案很长:
main()调用 main()时,堆叠帧会发生什么情况:
C不区分主要功能和其他任何功能。这是一个简单的,正常的递归情况。 'main'是特殊的,因为编译器附带的默认crt0.asm(或编译器中的任何名称)在完成基本初始化(如堆栈指针等)后调用main。
除了这种差异,没有什么,主要是特殊的。