Во-первых, использовать g++ main.cpp -pedantic
не очень полезно, потому что вы не включили никаких предупреждений. Добавьте -Wall -Wextra
к вашим флагам компилятора, а также -g
, чтобы вы могли отладить его.
Компиляция с -fsanitize=undefined
показывает ошибку времени выполнения, вызванную использованием нулевого указателя, где требуется действительный указатель:
/usr/include/c++/8/bits/stl_algobase.h:368:23: runtime error: null pointer passed as argument 2, which is declared to never be null
Segmentation fault (core dumped)
Это означает, что в вашей программе есть ошибка.
Компиляция с -D_GLIBCXX_DEBUG
добавит дополнительные проверки к std::vector
, и это сообщит вам о проблеме:
/usr/include/c++/8/debug/safe_iterator.h:374:
Error: attempt to advance a past-the-end iterator 4 steps, which falls
outside its valid range.
Objects involved in the operation:
iterator @ 0x0x7fffb09ceb90 {
type = __gnu_debug::_Safe_iterator<__gnu_cxx::__normal_iterator<unsigned char const*, std::__cxx1998::vector<unsigned char, std::allocator<unsigned char> > >, std::__debug::vector<unsigned char, std::allocator<unsigned char> > > (constant iterator);
state = past-the-end;
references sequence with type 'std::__debug::vector<unsigned char, std::allocator<unsigned char> >' @ 0x0x7fffb09cf050
}
Aborted (core dumped)
Вам следует запустить программу в отладчике, чтобы увидеть, где происходит это неправильное приращение итератора. Запуск программы в GDB, а затем использование ее команды up
для перемещения вверх по стеку показывает, что ошибка происходит здесь, в loadData
:
constexpr char MAGIC_START[4] = { 'G', 'R', 'I', 'B' };
constexpr char MAGIC_END[4] = { '7', '7', '7', '7' };
auto start = std::search(rawdata.cbegin(),
rawdata.cend(),
std::begin(MAGIC_START),
std::end(MAGIC_START));
auto end = std::search(rawdata.cbegin(),
rawdata.cend(),
std::begin(MAGIC_END),
std::end(MAGIC_END));
ByteVec data(start, end + sizeof(MAGIC_END));
^^^^^^^^^^^^^^^^^^^^^^^
Рассмотрим, что происходит, когда rawdata
не содержит символов MAGIC_START
, но содержит символы MAGIC_END
. start
и end
сформируют допустимый диапазон итераторов?
Рассмотрим, что происходит, когда rawdata
не содержит символов MAGIC_END
. Будет ли end + sizeof(MAGIC_END)
действительным?
Не следует считать, что два вызова std::search
работают как положено. Вы должны добавить некоторую проверку ошибок, проверяя, start == rawdata.end()
или end == rawdata.end()
. Если что-то из этого верно, что-то пошло не так (возможно, неверный ввод в строке rawdata
).
Вы также должны узнать, как использовать отладчик, и узнать о дополнительных инструментах, которые ваш компилятор предоставляет для обнаружения ошибок (например, параметры GCC -fsanitize=undefined
и -D_GLIBCXX_DEBUG
должны использоваться для подтверждения наличия ошибок, а GDB должен использоваться, чтобы найти, где эти ошибки происходят).