【问题标题】:Segmentation fault C++ in recursive function递归函数中的分段错误 C++
【发布时间】:2010-04-29 17:34:08
【问题描述】:

为什么我的递归函数会出现分段错误。每次我调用它时都会发生这种情况,当一个大于 4 的值作为参数时

#include <iostream>
#include <limits>

using namespace std;    

int printSeries(int n){
    if(n==1){       
        return 1;
    }
    else if( n==2){     
        return 2;
    }
    else if( n==3){
        return 3;
    }
    else if( n==4){
        return printSeries(1) + printSeries(2) + printSeries(3);
    }
    else{       
        return printSeries(n-3) + printSeries((n-2) + printSeries(n-1));
    }
}


int main(){

        //double infinity = numeric_limits<double>::max();

        for(int i=1; i<=10; i++){
            cout << printSeries(i) << endl;
        }

    return 0;

}

这工作正常,但我不确定返回正确的结果:

return printSeries(n-3) + printSeries(n-2) + printSeries(n-1);

【问题讨论】:

  • 我将第一个基本情况更改为
  • printSeries() 函数的顶部添加 std::cout &lt;&lt; n &lt;&lt; ',';

标签: c++ recursion segmentation-fault


【解决方案1】:
return printSeries(n-3) + printSeries( (n-2) + printSeries(n-1) );
//                                     ^^^^^^^^^^^^^^^^^^^^^^^^

不正确的括号嵌套会导致无限递归,从而导致堆栈溢出(segfault)。

考虑当 n = 4,

f(4) = 1 + f(2 + f(3))
     = 1 + f(2 + 3)
     = 1 + f(5)
     = 1 + [ f(2) + f(3 + f(4)) ]
     = ...

【讨论】:

  • 不应该抛出异常吗?
  • @the_drow:为什么要抛出异常?
  • @the_drow:为什么?这是完全有效的,它只会导致无限递归。
  • @the_drow:不幸的是,C++ 中没有std::programmer_error。不过,您可能想提出建议。
  • 我的意思是stackoverflow异常
【解决方案2】:

上面提到的括号问题是无限递归的根源。但是,即使您将案例 5 的括号修复为与案例 4 一样,代码也存在另一个问题:

printSeries(4) 递归调用 printSeries 3 次。
printSeries(5) 递归调用 printSeries 6 次。
printSeries(6) 递归调用 printSeries 12 次。
printSeries(10) 递归调用 printSeries 156 次。
printSeries(20) 递归调用 printSeries 69747 次。
printSeries(50) 递归调用 printSeries 超过 6 万亿次。

换句话说,你的代码比它应该做的方式更多。你明白为什么吗?

【讨论】:

    猜你喜欢
    • 2017-12-25
    • 1970-01-01
    • 2016-01-14
    • 2019-08-13
    • 2013-03-05
    • 2014-11-05
    • 2019-11-16
    相关资源
    最近更新 更多