使用以向量为输入的递归方法时的分段错误
Posted
技术标签:
【中文标题】使用以向量为输入的递归方法时的分段错误【英文标题】:Segmentation fault when using recursive method taking vector as input 【发布时间】:2017-09-10 11:47:39 【问题描述】:我正在尝试使用递归制作一个非常简单的过滤器,但由于某种原因,我不断收到这些 Seg Fault。
#include <iostream>
#include <vector>
#include <math.h>
class FilterGeneric
public:
std::vector<int> filter(std::vector<int>& v, std::vector<int>::iterator i); //set i=v.begin() in main
private:
virtual bool g(int x) =0;
std::vector<int> result;
;
std::vector<int> FilterGeneric::filter(std::vector<int>& v, std::vector<int>::iterator i)
if (i==v.end())
return result;
else
if (g(*i)==true)
result.push_back(*i);
i++;
return filter(v,i);
else
i++;
return filter(v,i);
class FilterOdd : public FilterGeneric
private:
bool g(int x);
;
bool FilterOdd::g(int x)
if ((x%2)!=0)
return true;
else
return false;
class FilterNonPositive : public FilterGeneric
private:
bool g(int x);
;
bool FilterNonPositive::g(int x)
if (x<0)
return true;
else
return false;
class FilterForTwoDigitPositive : public FilterGeneric
private:
bool g(int x);
;
bool FilterForTwoDigitPositive::g(int x)
if (x>=10)
return true;
else
return false;
int main()
std::vector<int> v;
std::vector<int>::iterator it=v.begin();
for (int i=0;i<20;i++)
v.push_back(pow(-1,i)*i);
std::cout<<std::endl;
FilterNonPositive fnp;
FilterForTwoDigitPositive ftd;
FilterGeneric *f1=&fnp;
FilterGeneric *f2=&ftd;
std::vector<int> r1;
std::vector<int> r2;
r1=f1->filter(v,it);
for (it=r1.begin();it!=r1.end();it++)
std::cout<<*it<<" ";
r2=f2->filter(v,it);
for (it=r2.begin();it!=r2.end();it++)
std::cout<<*it<<" ";
【问题讨论】:
堆栈空间不足? @user0042 我很抱歉我缺乏知识,但是有可能这么容易用完堆栈空间吗?我的意思是,这么简单的代码?我是说,我在这台电脑上玩游戏。 堆栈空间非常有限,使用递归函数调用时很容易用完。而是使用std::stack
和一个简单的循环。
@ViệtEngland我看不出堆栈空间与您的问题有任何关系。然而,Employed Russian 发布的答案肯定相关,我强烈建议您阅读并点击其中的链接。
【参考方案1】:
错误就在这里:
std::vector<int> v;
std::vector<int>::iterator it=v.begin();
for (int i=0;i<20;i++)
v.push_back(pow(-1,i)*i); // invalidates all iterators into "v"
...
r1=f1->filter(v,it); // using invalidated "it"
问题是v.push_back()
使所有迭代器无效如果向量需要调整大小。来自documentation:
如果新的 size() 大于 capacity() 则所有迭代器和引用(包括过去的迭代器)都将失效。否则只有过去的迭代器无效。
在 v
初始化后通过移动 it
初始化来纠正上述错误后,还有其他错误。
如果您使用g++
构建,您可以使用-D_GLIBCXX_DEBUG
来帮助您找到此类错误。
【讨论】:
有趣的是,pow
函数返回一个浮点值。提供的示例可能存在精度问题,因为将结果转换为浮点(用于参数)转换回整数。以上是关于使用以向量为输入的递归方法时的分段错误的主要内容,如果未能解决你的问题,请参考以下文章