Así que he estado recibiendo un mensaje misterioso de valores no inicializados de valgrind y ha sido un misterio saber de dónde se originó el valor malo.
Parece que valgrind muestra el lugar donde el valor unitario termina siendo utilizado, pero no el origen del valor no inicializado.
==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)
Como se puede ver, se vuelve bastante críptico ... especialmente porque cuando dice Class :: MethodX, a veces apunta directamente a ostream, etc. ¿Quizás esto se deba a la optimización?
==11366== by 0x81109ED: Snake::SnakeBody::syncBodyPos() (ostream:221)
Así. ¿Se me escapa algo? ¿Cuál es la mejor manera de atrapar los malos valores sin tener que recurrir al trabajo detectivesco de impresión súper larga?
Actualizar:
Descubrí lo que estaba mal, pero lo extraño es que valgrind no lo informó cuando se usó el valor incorrecto por primera vez. Fue utilizado en una función de multiplicación:
movespeed = stat.speedfactor * speedfac * currentbendfactor.val;
Donde speedfac era un flotador unitializado. Sin embargo, en ese momento no se informó y no es hasta que se imprima el valor que obtengo el error. ¿Existe una configuración para valgrind para cambiar este comportamiento?
Lo que esto significa es que está intentando imprimir / generar un valor que al menos no está inicializado parcialmente. ¿Puedes reducirlo para saber exactamente qué valor es? Después de eso, rastrea tu código para ver dónde se está inicializando. Lo más probable es que veas que no se está inicializando por completo.
Si necesita más ayuda, publicar las secciones relevantes del código fuente puede permitir que alguien le ofrezca más orientación.
EDITAR
Veo que has encontrado el problema. Tenga en cuenta que valgrind observa el salto o movimiento condicional en función de variables unitarias. Lo que eso significa es que solo emitirá una advertencia si la ejecución del programa se modifica debido al valor no inicializado (es decir, el programa toma una rama diferente en una declaración if, por ejemplo). Como la aritmética real no implicaba un salto o movimiento condicional, valgrind no le advirtió de eso. En su lugar, propagó el estado "no inicializado" al resultado de la declaración que lo utilizó.
Puede parecer contradictorio que no le advierte de inmediato, pero como señaló mark4o , lo hace porque los valores no inicializados se utilizan en C todo el tiempo (ejemplos: relleno en estructuras, la
realloc()
llamada, etc.) por lo que esas advertencias no serían Muy útil debido a la frecuencia de falsos positivos.fuente