Так что я получил какое-то загадочное сообщение с неинициализированными значениями от valgrind, и было довольно загадочно, откуда взялась плохая ценность.
Похоже, что valgrind показывает место, где в конечном итоге используется унифицированное значение, а не источник неинициализированного значения.
==11366== Conditional jump or move depends on uninitialised value(s)
==11366== at 0x43CAE4F: __printf_fp (in /lib/tls/i686/cmov/libc-2.7.so)
==11366== by 0x43C6563: vfprintf (in /lib/tls/i686/cmov/libc-2.7.so)
==11366== by 0x43EAC03: vsnprintf (in /lib/tls/i686/cmov/libc-2.7.so)
==11366== by 0x42D475B: (within /usr/lib/libstdc++.so.6.0.9)
==11366== by 0x42E2C9B: std::ostreambuf_iterator<char, std::char_traits<char> > std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::_M_insert_float<double>(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, char, double) const (in /usr/lib/libstdc++.so.6.0.9)
==11366== by 0x42E31B4: std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::do_put(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, double) const (in /usr/lib/libstdc++.so.6.0.9)
==11366== by 0x42EE56F: std::ostream& std::ostream::_M_insert<double>(double) (in /usr/lib/libstdc++.so.6.0.9)
==11366== by 0x81109ED: Snake::SnakeBody::syncBodyPos() (ostream:221)
==11366== by 0x810B9F1: Snake::Snake::update() (snake.cpp:257)
==11366== by 0x81113C1: SnakeApp::updateState() (snakeapp.cpp:224)
==11366== by 0x8120351: RoenGL::updateState() (roengl.cpp:1180)
==11366== by 0x81E87D9: Roensachs::update() (rs.cpp:321)
Как можно видеть, он становится довольно загадочным, особенно потому, что когда он говорит Class :: MethodX, он иногда указывает прямо на ostream и т. Д. Возможно, это связано с оптимизацией?
==11366== by 0x81109ED: Snake::SnakeBody::syncBodyPos() (ostream:221)
Просто так. Я что-то упускаю? Каков наилучший способ поймать плохие ценности, не прибегая к сверхдлинной работе детектива printf?
Обновить:
Я узнал, что было не так, но странно то, что Вальгринд не сообщал об этом, когда плохое значение было впервые использовано. Он был использован в функции умножения:
movespeed = stat.speedfactor * speedfac * currentbendfactor.val;
Где Speedfac был унитарным поплавком. Однако в то время об этом не сообщалось, и только когда должно быть напечатано значение, я получаю сообщение об ошибке. Существует ли параметр для valgrind, чтобы изменить это поведение?
Это означает, что вы пытаетесь распечатать / вывести значение, которое хотя бы частично неинициализировано. Можете ли вы сузить его, чтобы точно знать, что это такое? После этого проследите свой код, чтобы увидеть, где он инициализируется. Скорее всего, вы увидите, что он не полностью инициализирован.
Если вам нужна дополнительная помощь, публикация соответствующих разделов исходного кода может позволить кому-то предложить больше рекомендаций.
РЕДАКТИРОВАТЬ
Я вижу, вы нашли проблему. Обратите внимание, что valgrind следит за условным переходом или перемещением на основе унифицированных переменных. Это означает, что он выдаст предупреждение только в том случае, если выполнение программы будет изменено из-за неинициализированного значения (т. Е. Программа принимает другую ветвь в операторе if, например). Поскольку действительная арифметика не подразумевала условного прыжка или движения, valgrind не предупредил вас об этом. Вместо этого он распространял статус «неинициализированный» на результат оператора, который его использовал.
Может показаться нелогичным, что он не предупреждает вас немедленно, но, как отметил mark4o , он делает это, потому что неинициализированные значения используются в C все время (примеры: заполнение в структурах,
realloc()
вызов и т. Д.), Поэтому эти предупреждения не будут очень полезно из-за ложной положительной частоты.источник