Differenza tra dereferenziamento puntatore NULL e puntatore non inizializzato

Su blocchi di codice (C ++)

#include using namespace std; int main(){ int *p; cout<<*p; } 

produce valore immondizia, mentre

 #include using namespace std; int main(){ int *p=NULL; cout<<*p; } 

risultati in errore di runtime. Mi aspettavo un errore di runtime per entrambi (ideone produce errori di runtime per entrambi) perché entrambi sono cattivi puntatori. Come si può spiegare questo?

L’aspettativa di un errore di runtime è difettosa.

Dereferenziare un puntatore non inizializzato / non valido con un valore arbitrario può fare qualsiasi cosa .

Ciò significa che i potenziali sintomi vanno da:

  • non accade nulla
  • qualcosa accade
  • si verifica un errore di runtime
  • il tuo codice sorgente viene modificato spontaneamente per usare intestazioni standard appropriate invece di hackerare erroneamente nei “bit” di implementazione
  • il tuo atteggiamento nella sezione commenti è magicamente migliorato
  • il tuo gatto è stato assassinato
  • il tuo gatto non è stato assassinato
  • il tuo gatto viene ucciso e non ucciso
  • il tuo gatto uccide se stesso
  • un buco nero si apre nel tuo gatto
  • un gatto si apre all’interno di un buco nero

e così via.

Questo è vero anche per il dereferenziamento di NULL, ma l’hardware moderno delle materie prime tende a trattare specialmente le dereferenze NULL, di solito garantendo un errore di segmentazione per aiutare nella diagnostica. Ovviamente, una CPU non può farlo per valori di puntatori arbitrari, perché potrebbero essere validi per quanto ne sa!

Il tuo primo esempio,

 int *p; cout << *p; 

sta prendendo un puntatore selvatico e sta tentando di dereferenziarlo. Cosa c'è dall'altra parte di quel puntatore? È un percorso di sistema che causerà un errore di runtime? È l'indirizzo di x , un'altra variabile nel tuo programma? È un pezzo di memoria che sta usando il tuo browser web? Tentare di dereferenziare e leggere o scrivere in questa posizione è un comportamento indefinito , non c'è alcuna garanzia di cosa accadrà (il viaggio nel tempo è stato segnalato in casi estremi).

Anche il dereferenziamento di un puntatore nullo (un puntatore all'indirizzo 0 ) è anch'esso indefinito , ma probabilmente causerà un errore di segmentazione - un errore di runtime.

Nel primo codice, dato che non stiamo impostando il puntatore, sta assumendo un indirizzo di valore casuale … Che potrebbe avere qualche valore inutile. Ma nel secondo caso il puntatore non punta a nessun indirizzo, quindi ovviamente fallirà