gpt4 book ai didi

c - C中的无限递归

转载 作者:行者123 更新时间:2023-11-30 16:21:29 26 4
gpt4 key购买 nike

给定具有无限递归的 C 程序:

int main() {

main();

return 0;
}

为什么这会导致堆栈溢出。我知道这会导致以下线程中的 C++ 中的未定义行为 Is this infinite recursion UB? (并且作为侧节点,无法在 C++ 中调用 main())。然而,valgrind 告诉我这会导致堆栈溢出:

Stack overflow in thread 1: can't grow stack to 0x7fe801ff8

最后程序由于段错误而结束:

==2907== Process terminating with default action of signal 11 (SIGSEGV)
==2907== Access not within mapped region at address 0x7FE801FF0

这在 C 中也是未定义的行为吗?或者这真的会导致堆栈溢出,那么为什么会导致堆栈溢出?

编辑

1 我想知道C语言中是否允许无限递归?
2 这会导致堆栈溢出吗? (已得到充分答复)

最佳答案

每当调用函数时,参数都会被压入堆栈,这意味着堆栈段上的数据已“分配”。当函数被调用时,返回地址也会被CPU压入堆栈,因此它知道返回到哪里。

在您的示例中,这意味着不使用任何参数,因此唯一推送的是返回地址,该地址相当小(x86-32 架构上为 4 个字节),此外堆栈帧也进行了调整,这需要该架构上还有另外四个字节。

由此可知,一旦堆栈段耗尽​​,将无法调用 aynmore 函数,并向操作系统引发异常。现在可能会发生两件事。操作系统将异常转发回您的应用程序,您将看到这是堆栈溢出。或者操作系统可以尝试为堆栈段分配额外的空间,最多达到定义的限制,之后应用程序将看到堆栈溢出。

所以这段代码(我将其重命名为infinite_recursion(),因为无法调用main())...

int inifinite_recursion(void)
{
inifinite_recursion();
return 0;
}

...看起来像这样:

_inifinite_recursion:
push ebp ; 4 bytes on the stack
mov ebp, esp

call _inifinite_recursion ; another 4 bytes on the stack
mov eax, 0 ; this will never be executed.

pop ebp
ret

更新

关于定义递归的标准 C99,到目前为止我发现的最好的在第 6.5.2.2 节第 11 段中:

Recursive function calls shall be permitted, both directly and indirectly through any chain of other functions.

当然,这并没有回答是否定义了堆栈溢出时会发生什么。但至少它允许 main递归调用,而这在 C++ 中是明确禁止的(第 3.6.1 节第 3 段和第 5.2.2 节第 9 段)。

关于c - C中的无限递归,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54837299/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com