递归函数中的分段错误
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<unsigned int>(n))
)。
@UmNyobe 这段代码给了我错误的数字。 static vectorif ( n <= 1 ) return n;
这是不正确的 Fibonnaci(0)=1,我没有提到。这是您原始帖子中的错误之一。我测试了我发布的函数的正确性。【参考方案2】:
其他人评论了您的矢量缺少push_backs
。我要补充一点,您的向量对于您的函数的一次调用来说纯粹是本地的——它在递归调用堆栈上下没有作用域,因此它不会像您预期的那样运行。相反,您需要创建向量static
,或者最好通过引用每个递归调用来传递它。最好还是把它变成一个类。
【讨论】:
我的目标是让它成为一个类,我只是想先在一个简单的函数中尝试一下!以上是关于递归函数中的分段错误的主要内容,如果未能解决你的问题,请参考以下文章