После обновления с gcc / g ++ 8.1 до 9.1 и перекомпиляции моего кода большинство его тестов не прошло.Поэтому было сделано небольшое копание, и я обнаружил, что проблема была std::stable_sort
.
Как выяснилось, большинство моих звонков на std::stable_sort
были не нужны,то есть достаточно было бы позвонить std::sort
.Таким образом, я произвел замену там, где это было возможно, и тесты, касающиеся этих фрагментов кода, снова прошли успешно.
Теперь у меня есть только один вызов std::stable_sort
void MshReader::determinePhysicalEntitiesRange() {
// conns is not empty
std::stable_sort(this->conns.begin(), this->conns.end(),
[=](const auto& a, const auto& b){
return a[this->index] < b[this->index];
}
);
// acess some values of conns
}
Где conns - это std::vector<std::vector<int>>
, в котором хранятся соединения элементов.Сортировка выполняется на основе столбца index , его значение присваивается в заголовке класса, и все std::vector<int>
в conns имеют эту запись.
Еще один факт заслуживает вниманияупомянуто, что в отладке сборках (используется флаг компилятора "-g", "-O3" НЕТ) все тесты завершаются успешно .
Также на release builds (используется флаг «-O3», «-g» - НЕ), печатая значения conns до и после вызова std::stable_sort
, я обнаружил, что conns разрушен.
До
row:
0: 0 2 0 1
1: 0 2 1 2
2: 0 1 2 5
3: 0 1 5 8
4: 0 3 8 7
5: 0 3 7 6
6: 0 0 6 3
7: 0 0 3 0
8: 1 4 3 4 9
9: 1 4 3 9 6
10: 1 4 4 7 9
11: 1 4 6 9 7
12: 1 4 1 2 10
13: 1 4 1 10 4
14: 1 4 2 5 10
15: 1 4 4 10 5
16: 2 4 4 5 8 7
17: 2 4 0 1 4 3
После
row:
0: 0 0 6 3
1: 0 0 3 0
2: 0 1 2 5
3: 0 1 5 8
4: 0 2 1 2 // there were two rows with column 'index' = 2
5: 0 3 8 7
6: 0 3 7 6
7: 1 4 2 5 10 10 10 10 // this entry was previously on row 14; extra '10's
8: 1 4 3 4 9
9: 1 4 3 9 6
10: 1 4 4 7 9
11: 1 4 6 9 7
12: 1 4 1 2 10
13: 1 4 1 10 4
14: 1 4 2 5 10
15: 1 4 4 10 5
16: 2 4 4 5 8 7
17: 2 4 0 1 4 3
Вкл. Отладка сборок, std::stable_sort
выходовожидаемый результат.Кроме того, используется c++17
(флаг компилятора "-std = c ++ 17").
Следовательно,
Что-то не так с моим вызовомstd::stable_sort
?
Какие изменения в g ++ привели к такому поведению?
Почему это поведение появляется только в release builds?
Минимальный пример
#include <iostream>
#include <iomanip>
#include <vector>
#include <algorithm>
template<typename InputIt>
void print2D(InputIt cbegin, InputIt cend, std::string&& message) {
std::cout << message;
for (auto i = cbegin; i != cend; ++i) {
for (auto j = i->cbegin(); j != i->cend(); ++j) {
std::cout << "\t" << std::setw(3) << std::right << *j;
}
std::cout << std::endl;
}
std::cout << std::endl;
}
int main() {
int index = 1;
std::vector<std::vector<int>> conns{{0,2,0,1},{0,2,1,2},{0,1,2,5},{0,1,5,8},{0,3,8,7},{0,3,7,6},{0,0,6,3},{0,0,3,0},{1,4,3,4,9},{1,4,3,9,6},{1,4,4,7,9},{1,4,6,9,7},{1,4,1,2,10},{1,4,1,10,4},{1,4,2,5,10},{1,4,4,10,5},{2,4,4,5,8,7},{2,4,0,1,4,3}};
print2D(conns.cbegin(), conns.cend(), "\n\n\tbefore\n");
std::stable_sort(conns.begin(), conns.end(),
[=](const auto& a, const auto& b){
return a[index] < b[index];
}
);
print2D(conns.cbegin(), conns.cend(), "\n\n\tafter\n");
return 0;
}
Если вышеуказанное скомпилировано с
g++ -o main main.cpp -m64 -std=c++17 -O3
Выводится segmentation fault (core dumped)
.Однако, если флаг «-O3» не используется, ожидаемые результаты получаются.