Удалить элемент с конца вектора в C++
В этом посте мы обсудим, как удалить элемент с конца вектора в C++. Решение должно эффективно уменьшить размер вектора на единицу.
1. Использование std::vector::erase
Стандартное решение для удаления элемента из вектора — это std::vector::erase функция. Он переводит итератор в позицию, где элемент нужно удалить. Чтобы удалить элемент в конце вектора, передайте итератор, указывающий на последний элемент в векторе.
Вот как будет выглядеть код. Обратите внимание, что std::vector::end возвращает итератор не к последнему элементу вектора, а к последнему элементу.
Как удалить элемент вектора по индексу?
Пытаюсь удалить элемент вектора если поле соответствует тому, что я ввел с клавиатуры, найденный мною способ на просторах интернета удаляет только два элемента, хотя должен по идее удалять все, код функции:
void Delete(vector &train) < string dest; cout > dest; for (int i = 0; i < train.size(); i++) if (train[i]->GetDest() == dest) train.erase(train.begin() + i); >
- Вопрос задан более года назад
- 281 просмотр
Комментировать
Решения вопроса 1
Wataru @wataru Куратор тега C++
Разработчик на С++, экс-олимпиадник.
Не работает ваш код потому, что, допустим при i==3 вы удаляете элемент. Теперь элементом по индексу i будет следующий за удаленным элемент. Вы его не проверите и в конце итерации i увеличится на 1. Таким образом, следующие за удаляемым элементом вы просто пропустите.
Есть много способов исправить эту оплошность:
1) При удалении уменьшайте i на 1, чтобы следующее i++ от цикла for было отменено.
2) Вместо цикла for используйте while, где вы инкрементируете i только если элемент не удаляется.
3) Вместо if используйте цикл while, который удялял бы элемент в позиции i, пока его надо удалять (не забудьте проверить, что элемент, таки, существует — вы могли удалить последний элемент и i станет за границей массива).
4) (лучший вариант) Используйте remove. Мало того, что вам не надо изобретать велосипед, так этот метод еще и будет на порядок быстрее удаления по одному элементу. Потому что при каждом удалении у вас сдвигается часть массива и вы получаете квадратичное время работы на ровном месте.
Удаление элементов из вектора (STL). В чем ошибка?
Задаю массив целых чисел, хочу удалить все нули из него. Для этого использую функцию erase. Поскольку при удалении все элементы сдвигаются, возвращаю итератор на шаг назад (iter—). Почем так не работает и как правильно удалять произвольные элементы из вектора? (или никак и надо использовать другой контейнер?)
#include #include using namespace std; int main() < vectormas; vector::iterator iter; int N, temp; cout > N; for(int i = 0; i < N; ++i) < cin >> temp; mas.push_back(temp); > for(iter = mas.begin(); iter != mas.end(); ++iter) < if (*iter == 0) < mas.erase(iter); iter--; >> for(iter = mas.begin(); iter != mas.end(); ++iter) < cout return 0; >
- Вопрос задан более трёх лет назад
- 2389 просмотров
Удаление элемента std::vector C++
В случае, когда я пытаюсь удалить элемент, на который указывает итератор начала вектора, ничего не происходит и элемент выводится в обоих случаях и имеет один адрес. Если же я пытаюсь удалить элемент, указанный в коде, то программа крашится в рантайме:
Process finished with exit code -1073740940 (0xC0000374)
Видимо, я чего то не понимаю в работе с элементами по указателю. Подскажите, пожалуйста, как в итоге мне удалить элемент? Конкретизирую свой вопрос, я спросил немного не о том. Скажите, пожалуйста, что конкретно не так здесь:
for (int i = 0; i < currentRoom->getLoot().size(); ++i) < if (currentRoom->getLoot()[i]->getName() == item) if (currentRoom->getLoot()[i]->getPickable()) < inventory.push_back(currentRoom->getLoot()[i]); currentRoom->getLoot().erase(currentRoom->getLoot().begin() + i); return 0;>
На строке с erase приложение завершается с ошибкой
Process finished with exit code -1073740940 (0xC0000374)
Элемент, который я хочу удалить точно присутствует в векторе в момент удаления.
Отслеживать
user361068
задан 29 июл 2018 в 12:10
37 1 1 золотой знак 1 1 серебряный знак 7 7 бронзовых знаков
а почему вы выводите 0 элемент, а удаляете 1?
29 июл 2018 в 12:18
@pavel, это просто был метод «тыка», изначально я удалял первый
29 июл 2018 в 12:31
А что возвращает ваш getLoot()? Дайте угадаю: объект std::vector?
29 июл 2018 в 12:43
@AndrejLevkovitch да, std::vector
29 июл 2018 в 12:44
И как это по вашему должно работать? Вы же возвращаете временный объект — даже если у вас и произойдет удаление (а в данном случае это невозможно), то на начальный объект это никак не повлияет.
29 июл 2018 в 12:46
3 ответа 3
Сортировка: Сброс на вариант по умолчанию
Естественно программа крашится, так как вы пытаетесь удалить элемент, которого не существует, так как в данном случае у вас вектор состоит только из одного элемента. Если вы хотите удалить этот единственный элемент, то нужно убрать 1 из вашего же примера:
vector.erase(vector.begin());
В этом случае программа не будет крашится, а элемент удалится.
PS по поводу того, что элемент все равно отображается — в этом ничего удивительного, так как удаление элемента — это не его затирание. Вам следует поближе познакомится с памятью и понять как происходит занесение данных в память и их удаление. В кратце скажу: при «удалении» элемента ячейки памяти в которой находится элемент просто помечаются как вакантные. Они все еще существуют, но вот сохранение данных в них не гарантировано. В случае вектора — тоже самое. Ваша удаленная ячейка все еще будет содержать тот же указатель пока не будет перезаписана при следующем добавлении элемента.