Il valore del puntatore nullo rappresenta un "nulla" ben definito; è un valore del puntatore non valido che è garantito per il confronto non uguale a qualsiasi altro valore del puntatore. Il tentativo di dereferenziare un puntatore nullo comporta un comportamento indefinito e di solito porta a un errore di runtime, quindi è necessario assicurarsi che un puntatore non sia NULL prima di tentare di dereferenziarlo. Un numero di funzioni di libreria C e C ++ restituirà un puntatore nullo per indicare una condizione di errore. Ad esempio, la funzione di libreria malloc
restituirà un valore puntatore nullo se non è in grado di allocare il numero di byte che sono stati richiesti e il tentativo di accedere alla memoria tramite quel puntatore causerà (di solito) un errore di runtime:
int *p = malloc(sizeof *p * N);
p[0] = ...; // this will (usually) blow up if malloc returned NULL
Quindi dobbiamo assicurarci che la chiamata a malloc
sia riuscita controllando il valore di p
rispetto a NULL:
int *p = malloc(sizeof *p * N);
if (p != NULL) // or just if (p)
p[0] = ...;
Ora, tieni duro i calzini un minuto, questo diventerà un po 'accidentato.
C'è un puntatore nullo valore e un puntatore nullo costante , e i due non sono necessariamente uguali. Il puntatore nullo valore è il valore che l'architettura sottostante utilizza per rappresentare "da nessuna parte". Questo valore può essere 0x00000000 o 0xFFFFFFFF o 0xDEADBEEF o qualcosa di completamente diverso. Non dare per scontato che il puntatore nullo valore sia sempre 0.
Il puntatore nullo costante , OTOH, è sempre un'espressione integrale con valore 0. Per quanto riguarda il tuo codice sorgente , 0 (o qualsiasi espressione integrale che valuti a 0) rappresenta un puntatore nullo. Sia C che C ++ definiscono la macro NULL come costante del puntatore nullo. Una volta compilato il codice, il puntatore nullo costante verrà sostituito con il puntatore nullo appropriato valore nel codice macchina generato.
Inoltre, tieni presente che NULL è solo uno dei molti possibili valori del puntatore non valido ; se dichiari una variabile puntatore automatico senza inizializzarla esplicitamente, come
int *p;
il valore inizialmente memorizzato nella variabile è indeterminato e potrebbe non corrispondere a un indirizzo di memoria valido o accessibile. Sfortunatamente, non esiste un modo (portatile) per stabilire se un valore di puntatore non NULL è valido o meno prima di tentare di usarlo. Quindi, se hai a che fare con i puntatori, di solito è una buona idea inizializzarli in modo esplicito su NULL quando li dichiari, e impostarli su NULL quando non puntano attivamente a qualcosa.
Si noti che questo è più un problema in C che in C ++; C ++ idiomatico non dovrebbe usare i puntatori tanto.