2012-04-22 3 views
1
// Erase the missing items 
vector<AlignedFDRData>::size_type StandardNum = FDRFreq.at(0).fData.size(); 
vector<AlignedFDRData>::iterator iter = FDRFreq.begin(); 
while (iter != FDRFreq.end()){ 
    if(iter->fData.size() < StandardNum){ 
     FDRFreq.erase(iter); 
    } 
    else{ 
     ++iter; 
    } 
} 

Эта часть используется для удаления элемента вектора FDRFreq, в котором длина данных меньше, чем стандартное количество, но отладки утверждение не удалось: вектор итераторов несовместим. Я - зеленая рука в C++ STL, спасибо за вашу любезную помощь.C++ STL вектор итераторы несовместимый

+0

Вы аннулируете свой итератор, если вы «сотрите», подумайте об этом. вы должны сохранить итератор, который возвращается из вызова, чтобы стереть, как ответил Махмуд. – EdChum

ответ

6

Ваш код должен стать

while (iter != FDRFreq.end()){ 
    if(iter->fData.size() < StandardNum){ 
     iter = FDRFreq.erase(iter); 
    } 
    else{ 
     ++iter; 
    } 
} 

«вектор итераторы несовместимыми» означает, что итератор вы используете были признаны недействительными - то есть, нет никакой гарантии, что элементы он указывает, все еще существуют в этой ячейке памяти. Стирание векторного элемента аннулирует итераторы после этого местоположения. .erase возвращает новый, действительный итератор, который вы можете использовать вместо этого.

Если вы новичок в STL, я настоятельно рекомендую вам прочитать Скотт Майера Эффективное STLЭффективное использование C++, в то время как вы на него)

+1

Это не идиоматический способ по какой-то причине. Это вызовет как можно больше перераспределения и копий, поскольку элементы будут удалены. Не используйте его. – pmr

+0

Да, но это правильный ответ на вопрос, заданный ОП. Я добавил рекомендацию прочитать «Эффективный STL», который обеспечивает правильный метод. –

+1

Точка взята. Тем не менее, я не думаю, что ссылки на одну книгу полезны здесь. OP не найдет необходимую ему информацию, и его код будет по-прежнему ошибочным (да, я считаю, что ужасная производительность - это неправильный код). – pmr

8

Ваша проблема итератора недействительности после вызова std::erase. Предупреждение инициируется расширением отладки итератора в стандартной реализации библиотеки. erase возвращает итератор в новое допустимое местоположение после элемента стирания, и вы продолжаете итерацию оттуда. Однако это все еще очень неэффективно.

Используйте Erase-Remove Idiom, чтобы удалить данные с помощью предиката с vector.

FDRFreq.erase(std::remove_if(
       begin(FDRFreq), end(FDRFreq), 
       [&StandardNum](const AlignedFDRData& x) { 
        return fData.size() > StandardNum; }), 
       end(FDRFreq)); 
+0

Ваш пересмотренный ответ с объяснением, ссылками и правильным кодом теперь более корректен, чем мой. –

Смежные вопросы