Hani Goc
Hani Goc

Reputation: 2441

Runtime Error when erasing elements from std::vector

I have a vector index which contains the indices of elements that I want to remove from the vector words.

vector<int> Index;
vector<int> words;

I tried using this method, but my program crashes during runtime why? What is happening?

for(int t1 = 0; t1 < index.size(); t1++)
{
        words.erase(words.begin()+ index[t1])
}

Thank you.

Upvotes: 1

Views: 1902

Answers (4)

Hani Goc
Hani Goc

Reputation: 2441

vector<int>a = {0,0,0,0,1,1,1,1,0,0,0,0,1,0,0,0,0,0,0};
vector<int>index;
int t = 0;
while(t < a.size() && a[t] != 1)
{
    index.push_back(t);
    t = t + 1;
}

t = a.size()-1;
while( t > 0 && a[t] != 1)
{
    index.push_back(t);
    t = t - 1;
}
sort(index.begin(),index.end());
index.erase(std::unique(index.begin(), index.end()), index.end());
cout << "Before: ";
for(int i = 0; i <a.size();i++)
{
   cout << a[i] <<"   ";
}


cout << endl;
int counter = 0;
for(int i = 0; i < index.size();i++)
{
    a.erase(a.begin() + (index[i]-counter));
    counter = counter + 1;
}

cout <<"After: ";
for(int i = 0; i < a.size();i++)
{
   cout << a[i] <<"   ";
}

Upvotes: 0

Kevin MOLCARD
Kevin MOLCARD

Reputation: 2218

The problem here is that you are updating the size of the vector when you are erasing some elements in it.

Try this instead:

for(int t1 = index.size()-1; t1 >= 0; --t1)
{
    words.erase(words.begin()+index[t1])
}

Upvotes: 2

Andy Prowl
Andy Prowl

Reputation: 126432

It is hard to tell exactly why your program crashes without seeing how you declare and initialize words and index.

However, what is most likely to happen is that after removing an element from words, and after all the subsequent elements have been shifted to the left by one position, the indices in index may index positions which are beyond the new end of the vector.

When i is greater than the size of the vector, evaluating words.begin() + i will result in undefined behavior (which in your case is manifesting itself as a crash).

If your vector of indices is sorted in increasing order, just revert your loop:

for(int t1 = index.size() - 1; t1 >= 0; --t1)
{
    words.erase(words.begin() + index[t1]);
}

Or alternatively, you can use your original loop and sort the indices in decreasing order.

Upvotes: 3

Nick
Nick

Reputation: 25799

Try performing the operation in reverse. Subsequent indices are going to become invalid once you delete a later index.

I have assumed that your indices are ordered. If not then order them and then ensure you start by removing the largest index first.

Upvotes: 2

Related Questions