2016-03-31 3 views
1

Мои приложения требуют итерации по вектору и удаления определенных элементов, которые не удовлетворяют требованиям. Что является самым правильным способом? Я считаю, что следующий путь неверен. Результат: я получаю ошибку сегментации.Удалить элементы из вектора в C++ 11 во время итерации по нему

std::vector<ObjectX> vec1; 
//Fill in vec1 
std::vector<ObjectX>::iterator itVec1 = vec1.begin(); 

for(;itVec1 != vec1.end(); ++itVec1) { 
    if (Oracle(*itVec1)) vec1.erase(itVec1); 
} 
+0

Когда вы используете 'erase', он аннулирует итераторы и ссылки на или после точки стирания, в том числе end() итератор. –

+0

Я обычно повторяю его в обратном порядке и использую доступ к индексу вместо векторного итератора –

+0

Я чувствую себя двумя наиболее частыми вопросами C++, которые я вижу: как мне получить номера из 'std :: string' и почему моя программа segfault, когда аннулирование моего итератора. – erip

ответ

3

Когда вы звоните

vec1.erase(itVec1); 

вы аннулированию itVec1. После этого ++itVec1 не прав. Это приводит к неопределенному поведению. Вам нужно немного изменить свой код.

for(; itVec1 != vec1.end();) { 
    if (Oracle(*itVec1)) 
    { 
     itVec1 = vec1.erase(itVec1); 
    } 
    else 
    { 
     ++itVec1; 
    } 
} 

Вы можете удалить весь код котла пластины, используя Erase-Remove Idiom:

vec1.erase(std::remove_if(vec1.begin(), vec1.end(), Oracle), vec1.end()); 
+1

Этот цикл является анахронизмом. научите его правильному пути - erase/remove_if. –

0

Вы можете просто положить правильные предметы в новый вектор.