c/c++语言开发共享C中的递归深度是否有任何硬连线限制

正在讨论的程序试图使用recursion来计算sum-of-first-n-natural-numbers 。 我知道这可以使用一个简单的公式n*(n+1)/2但这里的想法是使用recursion

该计划如下:

 #include  unsigned long int add(unsigned long int n) { return (n == 0) ? 0 : n + add(n-1); } int main() { printf("result : %lu n", add(1000000)); return 0; } 

该程序在n = 100,000时运行良好,但当n的值增加到1,000,000 ,会导致Segmentation fault (core dumped)

以下内容取自gdb消息。

 Program received signal SIGSEGV, Segmentation fault. 0x00000000004004cc in add (n=Cannot access memory at address 0x7fffff7feff8 ) at kc:4 

我的问题:

    通常,限制将是堆栈的大小。 每次调用函数时,都会吃掉一定量的堆栈(通常取决于函数)。 吃掉的数量是堆栈帧,并在函数返回时恢复。 程序启动时,堆栈大小几乎几乎是固定的,要么是由操作系统指定的(通常可以在那里调整),要么甚至在程序中进行硬编码。

    要确切地看到每次调用函数需要多少堆栈空间并不容易,并且它将受制于编译器的优化级别。 在你的情况下,一个廉价的方法是每次打电话时打印; n可能会在堆栈上(特别是因为程序需要获取其地址 – 否则它可能在寄存器中),并且它的连续位置之间的距离将指示堆栈帧的大小。

    C中的递归深度没有理论限制。唯一的限制是您的实现,通常是有限的堆栈空间。
    (请注意,C标准实际上并不需要基于堆栈的实现。我不知道任何基于堆栈的实际实现,但请记住这一点。)

    SIGSEGV可能由任何数量的东西引起,但超过您的堆栈限制是一个相对常见的。 解除引用错误的指针是另一个。

    1)预计堆栈的消耗将减少并写为尾递归优化。

    gcc -O3 prog.c

     #include  unsigned long long int add(unsigned long int n, unsigned long long int sum){ return (n == 0) ? sum : add(n-1, n+sum); //tail recursion form } int main(){ printf("result : %llu n", add(1000000, 0));//OK return 0; } 

    C标准没有定义函数调用的最小支持深度。 如果确实如此,那么无论如何都很难保证,它会在第5.2.4 Environmental limits节的5.2.4 Environmental limits提到它。

    需要了解更多c/c++开发分享C中的递归深度是否有任何硬连线限制,也可以关注C/ C++技术分享栏目—计算机技术网(www.ctvol.com)!

      以上就是c/c++开发分享C中的递归深度是否有任何硬连线限制相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注计算机技术网(www.ctvol.com)!)。

      本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

      ctvol管理联系方式QQ:251552304

      本文章地址:https://www.ctvol.com/c-cdevelopment/979573.html

      (0)
      上一篇 2021年12月13日
      下一篇 2021年12月13日

      精彩推荐