Бесконечный цикл в clang, в gcc - работает

145
11 мая 2019, 21:30

Решили добавить тесты для компилятора clang помимо gcc. В итоге в одной функции получаем бесконечный цикл, и в минимальном примере размер карты не выводится. Почему так?

std::unordered_multimap<int, int> map = {{1, 2},
                                         {1, 5},
                                         {2, 3},
                                         {3, 7},
                                         {5, 1}}; // какая-то инициализация
for (auto&& key_value_pair : map) {
    auto[old_key, old_value] = key_value_pair;
    auto new_value = old_value + 1; // какое-то вычисление для нового значения
    map.insert({old_key, new_value});
}
std::cout << map.size();
Answer 1

Изменять контейнер во время прохода по нему с помощью ranged for loop - плохая идея.

Конкретно в случае unordered_multimap есть две проблемы.

Во-первых, .insert() может поставить элемент как перед текущим (т.е. перед key_value_pair), так и после, в зависимости от реализации.

Если unordered_multimap решит каждый раз будет ставить элемент после текущего, то цикл никогда не закончится.

Во вторых, что более важно:

std::unordered_multimap::insert()

If rehashing occurs due to the insertion, all iterators are invalidated. Otherwise iterators are not affected.

Rehashing рано или поздно произойдет при добавлении очередного элемента.

Тогда вы получите неопределенное поведение, потому что итератор, который используется ranged for для прохода по unordered_multimap, перестанет быть валидным.

READ ALSO
Передать любой тип как аргумент (с указанием типа) в C++

Передать любой тип как аргумент (с указанием типа) в C++

Видел в некоторых исходниках конструкцию типа Function<DWORD>(123)Подскажите пожалуйста:

153
Посчитать количество слов в строке

Посчитать количество слов в строке

Почему данный код не определяет количество слов? С другими символами работает, а с пробелом никак не хочет

144
UDP-приёмник сообщений на C++ Qt или Python PyQt

UDP-приёмник сообщений на C++ Qt или Python PyQt

Необходимо разработать UDP-приёмник, принимающий строку данных от сервера на другом ПК, и помещающий специнформацию в окно в соответствии...

134
Как вывести время на компьютере в c++?

Как вывести время на компьютере в c++?

Для кода нужно на вывести в цикле While, внутри оператора if время на ПК

151