Замена вектора декой

223
08 мая 2018, 00:20

Помогите понять в чем проблема:

Имеется тип с определением typedef std::vector<std::vector<chtype>> TetrisScreen;. Так как зачастую приходится добавлять в начало новые элементы (vector<chtype>) я решил заменить определение типа на typedef std::deque<std::vector<chtype>> TetrisScreen;, но получил проблему. В функции:

unsigned short Tetris::delete_all_solutions()
{
unsigned short rezult {};
for (auto i {screen_.begin()}; i != screen_.end(); ++i) {
    int counter {};
    for (auto j {i->begin()}; j != i->end(); ++ j) {
        if (*j == DEF_VALUE) {
            break;
        }
        else {
            counter++;
        }
    }
    if (counter == i->size()) {
        ++lines_;
        ++rezult;
        screen_.erase(i);
        screen_.push_front(decltype(screen_)::value_type (i->size(), DEF_VALUE));//insert(screen_.begin(), decltype(screen_)::value_type (i->size(), DEF_VALUE));
    }
}
return rezult;
}

возникает ошибка, которая приводит к краху программы. До этого все работало (в функции изменилась всего одна строка, предыдущее ее состояние закоментировано).

Answer 1

Вы в цикле по screen_ добавляете в него новые элементы. При этом итераторы становятся невалидными и программа закономерно падает. В случае вектора это тоже могло проявляться, но скорее всего там была заранее выделенная при помощи reserve память или оставшаяся от предыдущих действий. С деком такой подход не работает, т.к. нужно выделять память как минимум под два массива, а не под один и нет соответствующего интерфейса. Решение - заменить цикл по итераторам на цикл по индексам, только нужно не забыть, что при добавлении элемента в начало индекс станет указывать на предыдущий элемент и нужно сделать инкремент.

Answer 2

Я думаю, что проблема у вас в erase. После выполнение удаления, все последующие итераторы у вас становятся не валидными в очереди.
Я бы вам предложил бежать по итератору не с начала, а с конца, тогда невалидные итераторы у вас не будут получаться.

for (auto i {screen_.end() - 1}; i >= screen_.begin(); --i)
READ ALSO
Каретка в QLineEdit

Каретка в QLineEdit

Как сделать так, чтобы в QLineEdit автоматически (без нажатия клавиш влево-вправо) отображалась каретка?

230
Почему то не работает деление в программе. Язык C++

Почему то не работает деление в программе. Язык C++

Деление целого на целое в С++ дает целое число, замените 1 на 10

184
с++ WINAPI Edit text работает очень криво

с++ WINAPI Edit text работает очень криво

Начал изучать winapi в c++ написал простенькую программку которая меняет название окна на то что мы написали в текст боксе:

210
Реализвация личных сообщений Qt c++

Реализвация личных сообщений Qt c++

Есть чат, на qtcpserver и qtcpsocket соответственно, клиент нажимает отправить сообщение видно всем, как реализовать сообщения отдельному пользователю?

195