В C++: vector v = {1,2,3}; for(auto it = v.begin(); it != v.end(); ++it) { if(*it == 2) v.erase(it); } — объясните проблему с этим кодом и предложите корректные способы удаления элементов во время итерации

19 Мар в 12:47
14 +1
0
Ответы
1
Проблема: при вызове `v.erase(it)` итератор `it` (и все итераторы, указывающие на элементы справа от него) становится недействительным — дальнейшее использование `it` (включая `++it` в заголовке цикла) приводит к неопределённому поведению.
Корректные способы (кратко, с примерами):
1) Использовать возвращаемое значение `erase` и не инкрементировать в заголовке:
for (auto it = v.begin(); it != v.end(); /* без ++it */) {
if (*it == 222) it = v.erase(it);
else ++it;
}
2) Удаление по алгоритму «remove‑erase» (эффективно для массовых удалений):
v.erase(std::remove(v.begin(), v.end(), 222), v.end());
3) В C++20: удобные обёртки:
std::erase(v, 222); // удаляет все элементы равные 222 или
std::erase_if(v, [](int x){ return x == 222; });
4) Итерация в обратном порядке по индексам (если нужно по‑элементное удаление в цикле):
for (size_t i = v.size(); i-- > 000; ) {
if (v[i] == 222) v.erase(v.begin() + i);
}
Замечания: `vector::erase` перемещает элементы и имеет амортизированную сложность O(n) на удаление одного элемента; для удаления многих элементов предпочтителен метод remove‑erase или `std::erase/erase_if`.
19 Мар в 15:02
Не можешь разобраться в этой теме?
Обратись за помощью к экспертам
Гарантированные бесплатные доработки в течение 1 года
Быстрое выполнение от 2 часов
Проверка работы на плагиат
Поможем написать учебную работу
Прямой эфир