gpt4 book ai didi

c++ - 具有全局定义变量的递归比没有全局定义变量的递归函数获得更多堆栈。为什么? (跳入 C++)

转载 作者:太空宇宙 更新时间:2023-11-04 15:11:34 24 4
gpt4 key购买 nike

我正在通过 Alex Allain 的“Jumping into C++”等书籍学习 C++,并且正在学习递归。有一个程序示例可以计算出在出现“堆栈溢出错误”或在我的情况下出现“段错误”之前我的计算机可以处理多少次递归。

在使用给定的示例代码之前,我自己编写了一个简短的程序来测试它,它显示我的代码可以处理比给定示例代码多一倍的递归。我的问题:为什么会这样,因为它几乎是相同的模式——一个函数调用自身并迭代一个整数。

  1. 为什么在出现错误之前要进行两倍以上的递归?在我的理解中,两种算法都使用了相同数量的堆栈,并且在我的理解中,它们应该使用或多或少相同的数量。

第二,为什么是段错误而不是堆栈溢出?

我真的很想了解 C++ 编程,并希望能够编写使用最少系统资源的“廉价”程序,这确实是必要的。

我的代码:

#include <iostream>
using namespace std;


int i = 1;

void recurse ()
{

i = i + 1;
cout << "number: " << i << endl;

recurse();
}

int main()
{
recurse();
}

书中的代码示例:

#include <iostream>

using namespace std;


void recurse(int count)
{
cout << count << endl;
recurse(count + 1);
}

int main()
{
recurse(1);
}

我的输出: Output Screenshot of both examples on my system to see the difference i amreferring to

使用编译器 Linux g++ -std=c++17 (Arch Linux)

最佳答案

两个版本的代码都有未定义的行为。编译器可以很容易地证明 recurse 函数会无限递归,并且最终也会出现整数溢出。

C++ 标准明确指出,对具有未定义行为的程序的行为没有限制。你可能会遇到堆栈溢出、段冲突、你的硬盘可能被格式化、核导弹可能被发射、恶魔可能从你的 Nose 里飞出来、程序可能什么都不做,或者(最糟糕的是)它可能不小心做了什么你想要的。

因此,使用具有未定义行为的 C++ 程序来测试系统的极限或多或少毫无意义。

如果您删除输出,请参阅此处了解两个编译器如何在优化下转换您的代码:
https://godbolt.org/z/Lqln9n

注意 clang 如何看到未定义的行为并将其替换为“什么都不做并返回”。你不会在那个编译器上崩溃,程序什么都不做!并且 MSVC 将无限递归优化为平凡的无限循环(loop: jmp loop)。它会永远重复那条指令,而不是得到警告中提到的堆栈溢出。

混合输出后,编译器可能会再次做不同的事情。但是在任何情况下,除了“编译器决定那样做”之外,您都不会从运行程序中得到任何有意义的答案。您可以检查生成的汇编代码(见上文)以查看编译器做了什么,然后用它来解释您看到的行为。但我必须重申,给定的 C++ 代码没有定义的行为,可能会做任何事情

关于c++ - 具有全局定义变量的递归比没有全局定义变量的递归函数获得更多堆栈。为什么? (跳入 C++),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57972701/

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