Ошибка при удалении элемента в deque через итератор

109
20 июля 2019, 12:50

myDeque.erase(min) выдает ошибку: cannot seek value-initialized deque iterator

void sort(deque<int> &myDeque)
{
    for (int i = 0; i < myDeque.size(); i++)
    {
        auto currentPosition = myDeque.begin() + i;
        auto min = currentPosition;
        for (int j = i + 1; j < myDeque.size(); j++)
        {
            if (*min > *currentPosition)
            {
                min = currentPosition;
            }
            currentPosition++;
        }
        myDeque.push_front(*min);
        myDeque.erase(min);
    }
}
Answer 1

Метод push_front в std::deque инвалидирует все итераторы данного контейнера. В том числе ваш min. По этой причине вызов

myDeque.erase(min);

приводит к неопределенному поведению.

Сначала делайте erase, а уж потом push_front, предварительно сохраняя значение.

Answer 2

Как я понял, вы таким странным образом пытаетесь сортировать контейнер std::deque по убыванию значений.

Во-первых, у вас имеется логическая ошибка.

Внутри этого цикла

    for (int j = i + 1; j < myDeque.size(); j++)
    {
        if (*min > *currentPosition)
        {
            min = currentPosition;
        }
        currentPosition++;
    }

значение итератора currentPosition должно в начале цикла быть рано min + 1, а не min, как это у вас имеет место.

auto currentPosition = myDeque.begin() + i;
auto min = currentPosition;

В результате у вас последний элемент контейнера не рассматривается в этом цикле.

То есть должно быть по крайней мере так

auto min = myDeque.begin() + i;
auto currentPosition = min + 1;

так как переменная j начинается с i + 1 в цикле.

    for (int j = i + 1; j < myDeque.size(); j++)
             ^^^^^^^^^    

Во-вторых, после этого предложения

    myDeque.push_front(*min);

Итератор min становится недействительным.

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

#include <iostream>
#include <iterator>
#include <deque>
template <typename T>
void sort_descending( std::deque<T> &myDeque )
{
    for ( typename std::deque<T>::size_type i = 0; i < myDeque.size(); i++ )
    {
        auto min = std::next( std::begin( myDeque ), i );
        for ( auto current = std::next( min ); current != std::end( myDeque ); ++current )
        {
            if ( *current < *min ) min = current;
        }
        auto value = *min;
        myDeque.erase( min );
        myDeque.push_front( value );
    }
}
int main() 
{
    std::deque<int> myDeque = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
    for ( const auto &item : myDeque ) std::cout << item << ' ';
    std::cout << '\n';
    sort_descending( myDeque );
    for ( const auto &item : myDeque ) std::cout << item << ' ';
    std::cout << '\n';
    return 0;
}

Вывод программы на консоль:

0 1 2 3 4 5 6 7 8 9 
9 8 7 6 5 4 3 2 1 0 

Нешаблонная функция (если именно такая вам нужна) не сильно отличается от шаблонной.

void sort_descending( std::deque<int> &myDeque )
{
    for ( std::deque<int>::size_type i = 0; i < myDeque.size(); i++ )
    {
        auto min = std::next( std::begin( myDeque ), i );
        for ( auto current = std::next( min ); current != std::end( myDeque ); ++current )
        {
            if ( *current < *min ) min = current;
        }
        auto value = *min;
        myDeque.erase( min );
        myDeque.push_front( value );
    }
}
READ ALSO
Параметр функции в c++

Параметр функции в c++

Вкратце можно сказать следующее

111
Как сравнить изображения на java?

Как сравнить изображения на java?

Есть ли встроенные методы, позволяющие сравнить изображения на полное сходство (Не просто == или imgequals(img2), ибо в первом это разные объекты,...

114
Android, java, view.setOnTouchListener

Android, java, view.setOnTouchListener

Был у меня recyclerview с адаптером и все было крутоЯ добавил view

119
Как связать поля из SQLite c textaria и labels в JavaFX?

Как связать поля из SQLite c textaria и labels в JavaFX?

Пишу программу на JavaFX И Scene BuilderВ качестве базы данных использую SQLite

129