【问题标题】: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 发布的答案肯定相关,我强烈建议您阅读并点击其中的链接。

标签: c++ class recursion vector segmentation-fault


【解决方案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 函数返回一个浮点值。提供的示例可能存在精度问题,因为将结果转换为浮点(用于参数)转换回整数。
猜你喜欢
  • 1970-01-01
  • 2021-05-23
  • 1970-01-01
  • 2016-01-19
  • 1970-01-01
  • 1970-01-01
  • 2018-01-13
相关资源
最近更新 更多