Il valore del puntatore null rappresenta un "nulla" ben definito; è un valore di puntatore non valido che garantisce un confronto diverso da qualsiasi altro valore di puntatore. Tentare di dereferenziare un puntatore nullo comporta un comportamento indefinito e di solito porta a un errore di runtime, quindi si desidera assicurarsi che un puntatore non sia NULL prima di provare a dereferenziarlo. Numerose funzioni di libreria C e C ++ restituiranno un puntatore null per indicare una condizione di errore. Ad esempio, la funzione di libreria malloc
restituirà un valore di puntatore nullo se non è in grado di allocare il numero di byte richiesti e il tentativo di accedere alla memoria tramite quel puntatore (di solito) porterà a 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 malloc
chiamata abbia avuto successo controllando il valore di p
NULL:
int *p = malloc(sizeof *p * N);
if (p != NULL) // or just if (p)
p[0] = ...;
Ora, tieniti stretto le calze un minuto, questo diventerà un po 'accidentato.
C'è un valore di puntatore null e una costante di puntatore null e i due non sono necessariamente gli stessi. Il valore del puntatore null è qualunque valore l'architettura sottostante usi 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 valore del puntatore null sia sempre 0.
La costante puntatore null , OTOH, è sempre un'espressione integrale con valore 0. Per quanto riguarda il codice sorgente , 0 (o qualsiasi espressione integrale che restituisce 0) rappresenta un puntatore nullo. Sia C che C ++ definiscono la macro NULL come costante puntatore null. Quando viene compilato il codice, la costante puntatore null verrà sostituita con il valore puntatore null appropriato nel codice macchina generato.
Inoltre, tenere presente che NULL è solo uno dei molti possibili valori di puntatore non validi ; se si dichiara una variabile del puntatore automatico senza inizializzarla esplicitamente, ad esempio
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 dire 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 esplicitamente su NULL quando li dichiari e impostarli su NULL quando non puntano attivamente a nulla.
Si noti che questo è più un problema in C che C ++; il C ++ idiomatico non dovrebbe usare così tanto i puntatori.