Форум программистов, компьютерный форум CyberForum.ru

Удаление элемента вектора в цикле. - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 30, средняя оценка - 4.97
ZaxarPal
1 / 1 / 0
Регистрация: 18.01.2011
Сообщений: 83
02.10.2011, 00:40     Удаление элемента вектора в цикле. #1
Как правильно удалить элемент вектора в цикле? remove_if не подходит.
Примерно вот такая структура программы:
Код
struct Ex
{
    char value;
    uint32 timer;
};

std::vector<Ex> List;

void Update(uint32 diff)
{
    for (std::vector<Ex>::iterator itr = List.begin(); itr != List.end(); ++itr)
    {
        if ((*itr).timer <= diff)
        {
            <выполнить операцию над (*itr).value>
            <удалить элемент>
        }
        else
            (*itr).timer -= diff;
    }
}
Вектор заполняется элементами. Функция Update вызывается каждые 100 миллисекунд. timer = 10000. Т.е. после добавления элемента в вектор по истечению 10 секунд нужно выполнить над ним операцию и удалить. Удалять пробовал с помощью List.erase(itr) но ловил краш. Попробовал сделать
Код
List.erase(itr);
--itr;
стало работать через раз. Почитал подробнее про вектор, понял что так делать нельзя. Но не понял как правильно решить проблему удаления элемента. Сохранять порядок элементов вектора не нужно.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
02.10.2011, 00:40     Удаление элемента вектора в цикле.
Посмотрите здесь:

C++ вставка элемента в заданную позицию, удаление элемента по заданной позиции, поиск заданного элемента
Заданный вектор А, состоящий из n элементов. Переставить компоненты вектора, размещенные после самого элемента вектора А C++
C++ Удаление элемента из вектора ( std::vector<Bullet> )
Удаление элемента из вектора C++
C++ Удаление [i][j] элемента из вектора типа string
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Deviaphan
Делаю внезапно и красиво
Эксперт C++
 Аватар для Deviaphan
1283 / 1217 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
02.10.2011, 08:56     Удаление элемента вектора в цикле. #2
Удаляя элемент из вектора, все итераторы становятся некорректными, поэтому ты не можешь использовать те же итераторы для продолжения обхода. Потому и валится у тебя.
Вообще, вектор не очень подходит для подобного использования, лучше используй список.
Цитата Сообщение от ZaxarPal Посмотреть сообщение
Но не понял как правильно решить проблему удаления элемента.
C++
1
itr = List.erase(itr);
Но есть проблема. После удаления, тебе нужно перейти к следующей итерации без инкремента итератора. --itr может помочь, но после удалении первого элемента могут быть проблемы.
ZaxarPal
1 / 1 / 0
Регистрация: 18.01.2011
Сообщений: 83
02.10.2011, 11:25  [ТС]     Удаление элемента вектора в цикле. #3
Почему list лучше вектора? После удаления итераторы остаются корректными? В моем случае выходит чаще всего как раз удаление элемента с начала вектора. Причем очень часто в списке находится лишь один элемент. Ведь удаляется элемент у которого таймер закончился, а закончится он быстрее как раз у первого.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
    for (std::vector<Ex>::iterator itr = List.begin(); itr != List.end(); )
    {
        if ((*itr).timer <= diff)
        {
            <выполнить операцию над (*itr).value>
            <удалить элемент>
        }
        else
        {
            (*itr).timer -= diff;
            ++itr;
        }
    }
Пробовал использовать такой код - все равно краш. Тестирую пока только на одном элементе в векторе.
Deviaphan
Делаю внезапно и красиво
Эксперт C++
 Аватар для Deviaphan
1283 / 1217 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
02.10.2011, 11:40     Удаление элемента вектора в цикле. #4
Цитата Сообщение от ZaxarPal Посмотреть сообщение
Пробовал использовать такой код - все равно краш.
Присваивание итератора сделал в момент удаления?

Цитата Сообщение от ZaxarPal Посмотреть сообщение
Почему list лучше вектора?
Цитата Сообщение от ZaxarPal Посмотреть сообщение
В моем случае выходит чаще всего как раз удаление элемента с начала вектора.
Для вектора это самый плохой вариант, т.к. приходится копировать все последующие элементы. В случае со списком будет просто удаляться элемент.
Если тебе не требуется индексированный доступ, в данном случае лучше использовать вектор.
ZaxarPal
1 / 1 / 0
Регистрация: 18.01.2011
Сообщений: 83
02.10.2011, 11:55  [ТС]     Удаление элемента вектора в цикле. #5
Цитата Сообщение от Deviaphan Посмотреть сообщение
Присваивание итератора сделал в момент удаления?
Нет, не сделал. Только что сделал - теперь не крашится. Так что все же лучше использовать вектор или список? Операции будут только аналогичные указанным в первом посте - уменьшение таймера. Если таймер закончился - доступ до переменно value и использование ее в нужной функции. Доступа по индексу я не использую.
Deviaphan
Делаю внезапно и красиво
Эксперт C++
 Аватар для Deviaphan
1283 / 1217 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
02.10.2011, 11:59     Удаление элемента вектора в цикле. #6
Тогда список.

Добавлено через 1 минуту
Цитата Сообщение от ZaxarPal Посмотреть сообщение
Только что сделал - теперь не крашится.
Но теперь у тебя элемент, идущий за удаляемым, выпадает из проверки. Т.е. если у двух элементов, стоящих подряд, истекёт время, то удалён будет только первый.
ZaxarPal
1 / 1 / 0
Регистрация: 18.01.2011
Сообщений: 83
02.10.2011, 12:03  [ТС]     Удаление элемента вектора в цикле. #7
Цитата Сообщение от Deviaphan Посмотреть сообщение
Но теперь у тебя элемент, идущий за удаляемым, выпадает из проверки. Т.е. если у двух элементов, стоящих подряд, истекёт время, то удалён будет только первый.
Это как-то поправить можно? Хотя это не особо критично. Функция вызывается примерно каждые 40-100 милисек. и шанс, что в списке будет больше 5 элементов довольно низкий. Т.е. сильно нагрузки от перебора быть не должно. В 80% случае в списке будет лишь 1 элемент.
Deviaphan
Делаю внезапно и красиво
Эксперт C++
 Аватар для Deviaphan
1283 / 1217 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
02.10.2011, 12:07     Удаление элемента вектора в цикле. #8
Я не прав, это ошибку ты уже поправил перенеся инкремент итератора.)

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
    for (std::vector<Ex>::iterator itr = List.begin(); itr != List.end(); )
    {
        if ((*itr).timer <= diff)
        {
            <выполнить операцию над (*itr).value>
            itr = <удалить элемент>
        }
        else
        {
            (*itr).timer -= diff;
            ++itr;
        }
    }
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
02.10.2011, 12:08     Удаление элемента вектора в цикле.
Еще ссылки по теме:

C++ Удаление элемента из вектора
C++ Удаление элемента вектора

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
ZaxarPal
1 / 1 / 0
Регистрация: 18.01.2011
Сообщений: 83
02.10.2011, 12:08  [ТС]     Удаление элемента вектора в цикле. #9
Хотя нет, это критично. Ведь тогда дважды выполнится код над переменной value... Значит все ок?
Yandex
Объявления
02.10.2011, 12:08     Удаление элемента вектора в цикле.
Ответ Создать тему
Опции темы

Текущее время: 09:16. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru