Solo qualche precisazione sulla terminologia, che sembra poco utile ma che invece è sostanziale
Per quanto riguarda la questione di ciò che accada dopo free ,il puntatore fa riferimento a un area di memoria indefinita
"Area di memoria indefinita" non è un termine corretto.
Il puntatore punta ad un'area di memoria non allocata al processo. Ovvero il processo non dispone del "set di indirizzi virtuali" prima allocati con la malloc.
E' un discorso complesso che ci porterebbe troppo in là e che prevede la conoscenza di quello che c'è dietro la "gestione della memoria per i processi".
levare la locazione del puntatore da maggior sicurezza .
"Levare la locazione del puntatore" è una terminologia non corretta.
Semplicemente si indica che il contenuto del puntatore deve essere posto uguale a NULL.
NULL è rappresentato da 0 che è un indirizzo particolare per i sistemi dato che l'indirizzo virtuale 0 non è utilizzabile dai processi. Quindi
ptr=NULL;
indica soltanto che il puntatore non punta a nessuna area di memoria valida per il processo.
In questo modo anche si usasse
Anzi, proprio perché NULL, se si usasse per sbaglio il puntatore, il programmatore si accorgerebbe subito del problema perché in questo caso non esisterebbe un "undefined behavior" ma una conseguenza obbligatoria (crash con codice 0xc0000005 violation error).
Per quanto riguarda la questione delle due chiamata di free ... causa un undefined behavior
Questa non è una condizione di errore (che viene causata). Forse non ci intendiamo con i termini.
UB significa che il comportamento del compilatore in questo caso
non è definito dallo standard e che questa condizione può portare a strani comportamenti diversi da caso a caso, da NIENTE a un CRASH. E' comunque una condizione da EVITARE.
- - - Aggiornato - - -
che è quello che stiamo discutendo qua
Sì, corretto con la sola correzione che il doppio free implica che il secondo opera su un puntatore non valido. Questo fatto NON è contemplato dallo standard e quello che può succedere non è definito e non è sempre uguale per ogni compilatore (neanche per ogni esecuzione dello stesso programma). Quindi può succedere di tutto, da niente ad un crash. Ma è comunque un grave errore prevedere nel codice un doppio free dello stesso puntatore.
è sempre meglio porre il puntatore uguale a NULL per evitare problemi
Sì, perché dopo la prima free se si usasse il puntatore non più valido potresti anche creare problemi senza accorgertene. Il NULL evita questo problema perché obbliga il runtime al crash.
Nel momento in cui io provo a fare una cosa del tipo free(&numero);
Lo standard del C implica che si segua sempre lo schema malloc-free. Quindi i puntatori validi su cui può operare la free sono quelli rilasciati in precedenza dalla malloc. Quello che fornisci in quel modo non è tra quelli presenti nelle tavole di allocazione (su cui operano malloc-free) e quindi hai un "comportamento indefinito" (da niente a crash) ma sicuramente non deallochi l'int.