Search code examples
c++vectorerase-remove-idiom

Crash when using erase–remove idiom


When i execute the code below containing erase–remove idiom , i get a crash (segmentation fault). Id like to know what is the problem.

class One
{
public:
    One() {}
    void print(){  std::cout << "print id: " << id << "\n"; }
    void setId(int i) { id =i;}
    int getID(){ return id;}
private:
    int id;
};
 
int main()
{
    std::vector<One*> v;
    std::vector<One*> v2;
 
 
    for (int i = 0; i < 10; ++i) {
        One* one = new One;
        one->setId(i);
        v.push_back(one);
        v2.push_back(one);
    }
 
    v.erase((std::remove(v.begin(), v.end(), v2[2]), v.end()));
 
    return 0;
}

Solution

  • This line of code:

    v.erase((std::remove(v.begin(), v.end(), v2[2]), v.end()));
    

    is the equivalent of this:

    v.erase((some_iterator, v.end()));
    

    where some_iterator is the return value of the call to std::remove.

    That now becomes the equivalent of:

    v.erase(v.end());
    

    The reason why is that the parentheses enclosed this statement:

    (some_iterator, v.end())
    

    into an expression that invokes the comma operator. The comma operator takes the value on the right of the comma, and uses that as the final value.

    The correction is to remove the excessive parentheses:

    v.erase(std::remove(v.begin(), v.end(), v2[2]), v.end());