This simple code for some reason works perfectly fine on my desktop but when I try it on my laptop only the first part (printing the elements of vector) works then the program ends and instead of saying "Process finished with exit code 0" it says
"Process finished with exit code -1073741819 (0xC0000005)". I don't know what's wrong with my laptop. Can anyone help me?
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<int> array{1, 2, 3, 4, 5};
vector<int>::iterator it;
int arraysize;
for (int i = 0; i < array.size(); i++) {
cout << array[i] << endl;
}
cout << " " << endl;
for (it = array.begin(); it < array.end(); it++) {
if(*it%2==0){
array.erase(it);
it--;
}
}
arraysize=array.size();
cout<<"size:"<<arraysize<<endl;
for (int i = 0; i < array.size(); i++) {
cout << array[i] << endl;
}
return 0;
}
This happens because of iterator invalidation, when you erase an element of the vector the iterator it
becomes invalidated leading to undefined behaviour, you can read more about this here Iterator invalidation rules
The problem is not with the computer but with the code.
array.erase(it);
invalidates the iterator it
, and any subsequent use of it has undefined behaviour.
The worst kind of undefined behaviour is the one that appears to work.
erase
returns an iterator to the element after the erased one, and you should use that.
for (it = array.begin(); it < array.end(); it++) {
if(*it%2==0){
it = array.erase(it);
it--;
}
}
or
it = array.begin();
while (it < array.end()) {
if(*it%2==0){
it = array.erase(it);
}
else {
it++;
}
}
Your program has undefined behaviour, you decrement an invalid iterator
array.erase(it); // it becomes invalid
it--; // Undefined
You can avoid this by removing elements with the "erase-remove" pattern
auto is_even = [](int i) { return i%2==0; };
array.erase(std::remove_if(array.begin(), array.end(), is_even), array.end());
Or in C++20
std::erase_if(array, is_even);
There is nothing wrong with your laptop. The problem is with the code. When you erase something from the vector, it invalidates the preexisting iterators following the erased elements. You may want to use the return value of erase
, which references the new reallocated location of the erased element's successor.
User contributions licensed under CC BY-SA 3.0