Il valore NULL

  1. in un puntatore si può mettere il valore 0
  2. il programma non può usare la zona di memoria che inizia dalla posizione 0
  3. questo valore viene denotato con NULL
  4. indica che il puntatore non contiene un indirizzo valido
  5. malloc ritorna questo valore se l'allocazione è fallita

Il valore di un puntatore indica una posizione della memoria. La memoria, a sua volta, è come un array, per cui la prima posizione è zero, e l'ultima posizione dipende dalla dimensione della memoria.

Al contrario degli array, la posizione di indice 0 della memoria non è accessibile al programma. In altre parole, il seguente programma nozero.c produce un errore in esecuzione.

int main() {
  int *p;

  p=0;

  printf("%d", *p);

  return 0;
}

Non è l'istruzione p=0 a generare l'errore, ma l'istruzione di stampa: togliendo quest'ultima non si produce nessun errore. L'errore è dovuto al fatto che la posizione di memoria di indice zero non è accessibile al programma.

Convenzionalmente, questo valore 0 viene usato per indicare che un puntatore non contiene un indirizzo di memoria valido. Nel seguito si vedranno diversi usi di questa regola. Dal momento il valore zero come indirizzo usato in diverse applicazioni, è stato definito un nome simbolico per questo valore: NULL. Questa costante è definita nel file stdlib.h: si può quindi includere questo file oppure scrivere per esteso la definizione all'interno dei programmi dove è necessaria.

Dato che la posizione di memoria 0 non è utilizabile dal programma, qualsiasi tentativo di accesso a questa posizione, sia in scrittura che in lettura, produce un errore. Quindi, dopo aver fatto p=0 oppure NULL, tentare di usare *p genera un errore. Istruzioni come *p=4 oppure a=*p producono quindi un errore.

Il valore NULL viene usato dalla funzione malloc per indicare che il tentativo di allocare (riservare) memoria è fallito. Questo accade ogni volta che la memoria disponibile non è sufficiente. Per esempio, se si tenta di allora un miliardo di byte, ma la memoria disponbile è minore, il tentativo di allocazione fallisce. In questo caso, malloc ritorna NULL per indicare che la memoria non è stata riservata.

Usare NULL come valore di ritorno (invece di un qualsiasi altro numero) permette di controllare se l'allocazione di memoria è riuscita oppure no. Infatti, dopo aver fatto la chiamata di funzione, possiamo verificare se il valore di ritorno è NULL:

  p=malloc(sizeof(int));
  if( p==NULL ) {
    printf("Non ho abbastanza memoria per l'allocazione\n");
    exit(1);
  }

In effetti, il controllo del valore di ritorno di malloc andrebbe fatto sempre. Non fare il controllo può portare a errore difficili da individuare.