递归函数中的分段错误

Posted

技术标签:

【中文标题】递归函数中的分段错误【英文标题】:Segmentation fault in recursive function 【发布时间】:2013-06-23 12:41:36 【问题描述】:

我最近第一次读到记忆化(我是菜鸟),我想尝试制作一个使用记忆化的斐波那契函数。这是我尝试过的,但任何超过 1 的东西都会给我一个分段错误。任何帮助表示赞赏!

unsigned int fibonacci( unsigned int n )

    vector<unsigned int> fibvector;
    if ( n <= 1 )
        return n;
    if ( fibvector.size() >= n )
        return fibvector[n];
    unsigned int add = fibonacci( n-1 ) + fibonacci( n-2 );
    fibvector[n] = add;
    return add;

【问题讨论】:

您尚未为向量分配内存,但您正在使用 [n] 访问其内容。 如何手动执行此操作?我以为向量会自己分配内存? 确实如此,但前提是您执行push_back(n) 之类的操作。当你使用[n] 时,它会返回一个对它没有在内部分配空间的内存地址的引用。只有在你使用push_back 之后,你才能这样做。 谢谢,我不知道 :) 【参考方案1】:
vector<unsigned int> fibvector; 

是一个局部变量。每次调用fibonacci(n) 都会创建一个没有元素的新向量。您可以通过将其设为静态来修复它。

static vector<unsigned int> fibvector(MAXELEMENTS); 

MAXELEMENTS 用于初始化目的。在这种情况下,您需要使用

进行测试
if(fibvector[n] != 0) return fibvector[n];

编辑:如果您不想需要固定数量的元素,您可以使用以下内容

unsigned int fibonacci( unsigned int n )

    static vector<unsigned int> fibvector;
    unsigned int fib;

    if ( fibvector.size() > n )
        return fibvector[n];
    if(n <=1)
       fib = n;
    
    else
       unsigned int v2 = fibonacci( n-2 );
       unsigned int v1 = fibonacci( n-1 );
       fib = v2 + v1;
    
    fibvector.push_back(fib);
    return fib;

这个想法是斐波那契(n)的递归方法将首先计算斐波那契(0),斐波那契(1),斐波那契(2)直到斐波那契(n)。这意味着它将按照 n 的自然顺序进行计算,并且 push_back 将准确地遵循此顺序。

【讨论】:

我会将此向量作为函数的引用参数,而不是将其声明为静态的。 非常感谢!但是你必须在开始时设置 maxelements 吗?我希望它没有最大元素。 @Arnstein:是的,你可以,但是你必须确保在它太小的时候重新生长它。正如 g-makulik 建议的那样,我建议将向量作为参考参数。你甚至可以重载你的函数以提供一个干净的接口(即fibonacci(n),将调用fibonacci(n,vector&lt;unsigned int&gt;(n)))。 @UmNyobe 这段代码给了我错误的数字。 static vector fibvector;无符号整数加 = 1;如果 ( n n ) 返回 fibvector[n]; if ( n > 1 ) unsigned int v1 = fibonacci( n-2 );无符号整数 v2 = 斐波那契(n-1);添加=v2+v1; fibvector.push_back( 添加 );返回添加; if ( n &lt;= 1 ) return n; 这是不正确的 Fibonnaci(0)=1,我没有提到。这是您原始帖子中的错误之一。我测试了我发布的函数的正确性。【参考方案2】:

其他人评论了您的矢量缺少push_backs。我要补充一点,您的向量对于您的函数的一次调用来说纯粹是本地的——它在递归调用堆栈上下没有作用域,因此它不会像您预期的那样运行。相反,您需要创建向量static,或者最好通过引用每个递归调用来传递它。最好还是把它变成一个类。

【讨论】:

我的目标是让它成为一个类,我只是想先在一个简单的函数中尝试一下!

以上是关于递归函数中的分段错误的主要内容,如果未能解决你的问题,请参考以下文章

递归函数的分段失败

iverilog递归函数导致分段错误

在递归函数上使用 unordered_map unordered_set 的分段错误

C函数调用分段错误[重复]

matlab分段+递归函数的表示方法

为啥 PHP 中的无限递归函数会导致段错误?