Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ STL vector erase [duplicate]

Tags:

c++

stl

vector

The problem is that when I run the function it crashes at the erase part and I cant figure out why.

void Grupa::del() {
    int size = studenti.size();
    for (int i=0; i<size; i++) {
        if (studenti[i].materia1<5 && studenti[i].materia2<5 && studenti[i].materia3<5) {
        studenti.erase(studenti.begin()+i);
        }
    }
}
like image 632
Czoka Avatar asked Mar 19 '26 10:03

Czoka


2 Answers

When you erase an element, the vector gets smaller; but you're still using the original size, and falling off the end. Also, you don't want to increment i after erasing, otherwise you'll skip the element after the erased one. So you want something like:

for (size_t i = 0; 
     i != studenti.size(); // don't hoist out of the loop
     /* don't increment here */) 
{
    if (...) {
        studenti.erase(studenti.begin()+i);
    } else {
        ++i;
    }
}

Or see other answers for the "erase-remove" idiom, which is a nice, and perhaps more efficient, way of avoiding this kind of error-prone logic.

like image 83
Mike Seymour Avatar answered Mar 21 '26 00:03

Mike Seymour


It looks like you should be using an STL algorithm, std::remove_if, instead of this, which conveniently avoids the problems other answerers have pointed out already. Consider this instead:

studenti.erase(std::remove_if(studenti.cbegin(), studenti.cend(), [](Student const& currentStudent) {
    return currentStudent.materia1<5 && currentStudent.materia2<5 && currentStudent.materia3<5;
}), studenti.cend());

Note that this has the advantage over your solution in that it takes linear time relative to the number of elements in the vector, while the for/erase solution takes quadratic time.

like image 23
Billy ONeal Avatar answered Mar 21 '26 00:03

Billy ONeal



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!