使用以向量为输入的递归方法时的分段错误

时间:2017-09-10 11:47:40

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

我正在尝试使用递归制作一个非常简单的过滤器但由于某种原因,我不断得到这些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<<" ";
    }

}

1 个答案:

答案 0 :(得分: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

  

如果new size()大于capacity(),则所有迭代器和引用(包括last-the-end迭代器)都将失效。否则只有过去的迭代器无效。

it初始化后,通过移动v初始化来纠正上述错误后,还会出现其他错误。

如果您使用g++进行构建,则可以使用-D_GLIBCXX_DEBUG来帮助您找到此类错误。