所以我对C ++还是很陌生,我正尝试使用递归来生成斐波那契数,对吗?除了当我尝试索引下一个值时,我需要增加索引,而该函数不会让我增加它。
我知道的是,我已在调试模式下运行它并跨过函数-它在fibGen函数内部连续循环,而我保持恒定值1(当我在主函数中调用fibGen时,参数是(startingSeq,1,13),其中startingSeq是另一个值为{1,1}的向量
代码可以很好地构建和编译,但是当我运行它时,我得到了一个内存分配错误,这是由似乎有无限循环的原因引起的。
我做错了什么?为什么“ i”没有增加?
我已经尝试通过在递归的fibGen调用中(在else语句中)使用i ++来增加i,我已经尝试在函数调用之外使用i ++,并且现在尝试了其中存在i +的内容= 1,然后让我通过。
我本来也没有底部的“ return fibSeq”,因为在那里没有意义,但是我把它放进去是因为如果没有它,vscode不会编译,说永远不会到达fibGen的末尾(这很有意义,而且当此问题解决后,我认为可以将其消除,但是目前它就在那里,以便程序可以编译)
std::vector<int> fibGen(std::vector<int> fibSeq, int i, int max){
if(fibSeq[i] >= max){
return fibSeq;
}else{
fibSeq.push_back(fibSeq[i] + fibSeq[i-1]);
i+=1;
fibGen(fibSeq, i, max);
}
return fibSeq;
}
输出应该是包含斐波那契序列的向量,并且我遇到了内存分配错误(如上所述)
答案 0 :(得分:3)
实际上,您的代码有效。您只是次优地处理结果向量。与您的声明:
std::vector<int> fibGen(std::vector<int> fibSeq, int i, int max)
您将始终传递矢量的副本(并且您永远不会使用返回的值)。相反,您可能想要做的是处理相同的数据。为此,请使用对向量的引用(用&
表示)。然后,您无需返回任何内容:
void fibGen(std::vector<int>& fibSeq, int i, int max) {
if (fibSeq[i] >= max) {
return;
}
else {
fibSeq.push_back(fibSeq[i] + fibSeq[i - 1]);
i += 1;
fibGen(fibSeq, i, max);
}
}
void main(void) {
std::vector<int> fib = { 1, 1 };
fibGen(fib, 1, 34);
for (auto i : fib)
std::cout << i << std::endl;
}
答案 1 :(得分:0)
因此,直到我意识到在您的实际代码中,您是在执行此操作而不是在发布的代码中进行操作,我才能重现该错误:
std::vector<int> fibGen(std::vector<int> fibSeq, int i, int max){
if(fibSeq[i] >= max){
return fibSeq;
}else{
fibSeq.push_back(fibSeq[i] + fibSeq[i-1]);
i+=1;
fibGen(fibSeq, i, max);
}
}
至少在Visual Studio 2010中,它可以正常编译,但是在运行时引发了一个错误,我相信这就是您所描述的。所以我假设我已经复制了它。
引发错误的原因是因为you are invoking C++'s infamous undefined behavior。 C ++ permits anything to happen中的未定义行为,如未编译失败,但引发运行时错误。
修复很简单。您只需要在所有执行路径中返回一个值。或者,简而言之,只需执行以下操作:
std::vector<int> fibGen(std::vector<int> fibSeq, int i, int max){
if(fibSeq[i] >= max){
return fibSeq;
}else{
fibSeq.push_back(fibSeq[i] + fibSeq[i-1]);
i+=1;
return fibGen(fibSeq, i, max);
// Notice we are returning the value of the recursive call to fibGen().
// We can do this because we have already modified the vector the way we need to,
// so just simply returning the value is fine
}
}
当然,您也可以改用Nico Schertler's suggestion:
void fibGen(std::vector<int>& fibSeq, int i, int max) { if (fibSeq[i] >= max) { return; } else { fibSeq.push_back(fibSeq[i] + fibSeq[i - 1]); i += 1; fibGen(fibSeq, i, max); } }
应该注意,不从void函数返回值并不是未定义的行为(据我所知),但实际上是void的工作原理,因此该函数可以不返回值就可以了。