Почему я не могу удалить последний элемент вектора - PullRequest
5 голосов
/ 08 марта 2011

У меня есть вектор stl, состоящий из нескольких элементов. Мне нужно перебрать этот вектор и удалить элементы, которые соответствуют некоторым критериям. Поэтому я написал этот код

for (int j = imageDataVector.size()-1; j >= 0; j--) {
    if(imageDataVector[i] < threshold)
        imageDataVector.erase(imageDataVector.end() - j);
}

Этот код прекрасно работает почти во всех случаях, однако, если все элементы вектора соответствуют критериям, я получаю ошибку:

vector erase iterator outside the range

Эта ошибка возникает, если в векторе остался только один элемент. Что я делаю не так?

Ответы [ 3 ]

11 голосов
/ 08 марта 2011
if(imageDataVector[i] < threshold)
        imageDataVector.erase(imageDataVector.end()-j);

Вероятно, должно быть:

if(imageDataVector[j] < threshold)
        imageDataVector.erase(imageDataVector.begin()+j);

РЕДАКТИРОВАТЬ: для полноты, пути удаления-удаления и пути итератора:

imageDataVector.erase(std::remove_if(imageDataVector.begin(), imageDataVector.end(), std::bind2nd(std::less<vector_data_type>(), threshold)), imageDataVector.end());

vector<type>::iterator it = imageDataVector.begin();
while (it != imageDataVector.end()) {
  if (*it < threshold)
    it = imageDataVector.erase(it);
  else
    ++it;
}
6 голосов
/ 08 марта 2011

Вы смешиваете прямую и обратную индексацию.

Я бы подумал вместо этого использовать std::remove_if.Таким образом, если вы удаляете несколько элементов, вы не сдвигаете весь вектор вперед при каждом стирании.

Это будет выглядеть примерно так:

imageDataVector.erase(std::remove_if(imageDataVector.begin(), imageDataVector.end(), std::bind2nd(std::less<data_type>(), threshold)), imageDataVector.end());

Поочередно попробуйте следующее, отметивчто это приведет к большому перемещению, если вы удалите несколько элементов из вектора.

for (int j=imageDataVector.size()-1 ;j>=0;j--)
{
    if(imageDataVector[i] < threshold)
        imageDataVector.erase(imageDataVector.begin()+j);
}
3 голосов
/ 08 марта 2011

Вы пытаетесь отсчитать j до нуля, а imageDataVector.end() - 0 не является допустимым итератором. В стандартных контейнерах библиотеки C ++ конечный итератор указывает один за последним элементом, а не за последним.

...