Dovrei preoccuparsi di “Salto condizionato o mossa dipende dal valore Non inizializzato (s)”?
Domanda
Se hai utilizzato MemCheck (da Valgrind) probabilmente sarete familiarità con questo messaggio ...
Salto condizionato o mossa dipende dal valore non inizializzato (s)
Ho letto su questo e si verifica solo quando si utilizza un valore non inizializzato.
MyClass s;
s.DoStuff();
Questo funziona perché s
viene inizializzato automaticamente ... Quindi, se questo è il caso, e funziona, perché MemCheck dirmi che è inizializzata? Se il messaggio viene ignorato?
Forse ho capito male dove l'errore mi stava dirigendo. Dal manuale Valgrind, il frammento di reale erronea è ...
int main()
{
int x;
printf ("x = %d\n", x);
}
Tuttavia, nel mio codice, non riesco a vedere nulla di simile. Ho notato però che la funzione in cima alla pila traccia MemCheck mostra me è una funzione virtuale; questo potrebbe essere qualcosa a che fare con esso?
==14446== Conditional jump or move depends on uninitialised value(s)
==14446== at 0x414164: vimrid::glut::GlutApplication::FinishRender() (GlutApplication.cpp:120)
==14446== by 0x422434: vimrid::demos::filterdemos::FilterDemo3::Render() (FilterDemo3.cpp:260)
==14446== by 0x412D3D: vimrid::VimridApplication::UpdateAndRender() (VimridApplication.cpp:93)
==14446== by 0x4144BA: vimrid::glut::GlutApplication::glutHandleDisplay() (GlutApplication.cpp:201)
==14446== by 0x41486A: vimrid::glut::GlutApplication::glutCallbackDisplay() (GlutApplication.cpp:277)
==14446== by 0x54D9FAA: (within /usr/lib64/libglut.so.3.8.0)
==14446== by 0x54DDA4A: fgEnumWindows (in /usr/lib64/libglut.so.3.8.0)
==14446== by 0x54DA4A3: glutMainLoopEvent (in /usr/lib64/libglut.so.3.8.0)
==14446== by 0x54DAEB5: glutMainLoop (in /usr/lib64/libglut.so.3.8.0)
==14446== by 0x413FF8: vimrid::glut::GlutApplication::Run() (GlutApplication.cpp:112)
==14446== by 0x41249D: vimrid::Launcher::runDemo(vimrid::VimridSettings&) (Launcher.cpp:150)
==14446== by 0x412767: vimrid::Launcher::Launch(int, char**) (Launcher.cpp:62)
Aggiornamento 1:
Ho preso uno sguardo al GlutApplication.cpp: 120, e sembra che la variabile non inizializzata era stata passata a una funzione su quella linea. Semplice!
Soluzione
Puoi pubblicare un campione più completo? E 'difficile capire come ci sarebbe stato quel particolare errore con qualche forma di goto o di flusso cambiando dichiarazione.
I più comunemente vedo questo errore nel codice come il seguente
MyClass s1;
...
if ( someCondition ) {
goto Foo:
}
MyClass s2;
Foo:
cout << s2.GetName();
Questo codice è fondamentalmente errato. Il motivo per cui è che anche se S2 ha un costruttore, non è eseguita se someCondition è vero. La dichiarazione goto salterà sopra l'inizializzazione e l'ultima riga del s2 programma sarà inizializzato ed essenzialmente puntare alla spazzatura.
Modifica
Si consiglia inoltre di controllare questa pagina che fornisce suggerimenti su come decifrare questo particolare errore valgrind
https://computing.llnl.gov/code/memcheck/#deciphering4
Addendum
Un'altra causa comune per questo che ho appena trovato è quando si passa su alcune costanti integer a una funzione variadic, che vengono messa in pila come int, ma quando il chiamato ottiene come anela, hai un problema su macchine a 64-bit.
ero quasi sul punto di rinunciare e basta considerare valgrind essere stupido, allora ho capito che semplicemente il cast di correzioni tempo.
Quindi la mia conclusione è:. Prendere sul serio questi messaggi
Altri suggerimenti
È possibile aggiungere il --track-origins=yes
bandiera per Valgrind e vi darà informazioni sulle fonti di dati non inizializzate. Esso viene eseguito più lentamente, ma può essere utile.
Fonte: Valgrind Manuale Utente
Se Valgrind afferma che un valore non viene inizializzato, poi nel 99,5% è in realtà non inizializzato. Normalmente, quando i rapporti del compilatore utilizzano di un valore Non inizializzato (-Wuninitialized nel GCC), si controlla la linea srotola, come valore Non inizializzato può essere dichiarata (e non inizializzato), per esempio 10 livelli di funzione inline "chiamate" (o modello si srotola) più in alto, di rapporto GCC reale. Valgrind fa la stessa cosa, ma in fase di esecuzione . Quindi si dovrebbe verificare tutto il percorso in cui il valore Non inizializzato viaggiato da luogo di essere dichiarato (e non inizializzato), al posto in cui è effettivamente utilizzato. Il percorso può essere ad esempio: cascata di chiamate di funzione, dove ogni funzione passa suoi argomenti (ed eventualmente valore Non inizializzato) alla funzione successiva. Valgrind riporterà in ultima funzione, quando il valore è effettivamente utilizzato.
In genere non si deve ignorare quello che gli stati Valgrind. Valgrind non è un semplice programma di traccia. Esso può essere visto come una macchina virtuale:
Valgrind è in sostanza un virtuale macchina usando just-in-time (JIT) tecniche di compilazione, tra cui ricompilazione dinamica. niente da il programma originale viene mai eseguito direttamente sul processore host. Invece, Valgrind prima traduce il programma in una forma più semplice temporanea chiamato rappresentazione intermedia (IR), che è un processore neutrale, modulo SSA-based. Dopo la conversione, uno strumento (vedi sotto) è libero di fare qualunque trasformazioni vorrebbe sul IR, prima di Valgrind traduce IR di nuovo in codice macchina e lascia il processore host eseguirlo. Nonostante si potrebbe utilizzare traduttore dinamico (che è, i processori host e di destinazione sono da diverse architetture), essa non lo fa. Valgrind ricompila binario l'esecuzione di codice su host e di destinazione (o simulato) CPU della stessa architettura. (Wikipedia)
Sarebbe molto utile se si può inviare più di codice, in particolare dalla parte dove Valgrind pensa l'errore è.
Se questo accade ogni volta che si crea un'istanza della classe, probabilmente dimenticato di inizializzare uno dei membri nel costruttore.
E sì:. Si dovrebbe preoccupare di questo errore, quei ragazzi possono davvero mordere
In macchina 64-bit. Solitamente, int richiede 4 byte di memoria. Ma molto tempo avrà 8 byte in memoria. Così semplicemente fare riferimento un valore int come formato di tempo causerà risultato del tutto errata. Un convertito è necessaria in questa situazione.
L'errore non sembra venire dal codice, ma una libreria che si utilizza.
Valgrind è dotato di una certa soppressione errore predefinito, ma che probabilmente non copre la libreria che si sta utilizzando.
Gli strumenti di controllo degli errori rilevare numerosi problemi nelle librerie di base, come ad esempio la libreria GNU C, e le librerie client X11, che vengono pre-installato sul sistema GNU / Linux. Non si può facilmente risolvere questi, ma non si vuole vedere questi errori (e sì, ci sono molti!) Così Valgrind legge un elenco di errori di sopprimere all'avvio. Un file di soppressione di default viene creato dallo script ./configure quando il sistema è costruito.
È possibile creare il proprio che si sa sono irrilevanti al codice.
Vedere la simile domanda SO Perché Valgrind non piace il mio utilizzo di glutCreateWindow?