OK, c'è una buona dose di confusione spiegare esattamente che cosa ordinare le necessarie free()
le chiamate devono essere in, quindi mi prova a chiarire che cosa cercano le persone e perché.
Partendo dalle basi, per liberare la memoria che è stata assegnata utilizzando malloc()
, è sufficiente chiamare free()
esattamente il puntatore che ti sono stati forniti da malloc()
.Quindi, per questo codice:
int **a = malloc(m * sizeof(int *));
hai bisogno di una corrispondenza:
free(a);
e per questa linea:
a[i]=malloc(n * sizeof(int));
hai bisogno di una corrispondenza:
free(a[i]);
all'interno di un ciclo simile.
Dove questo diventa complicato è l'ordine in cui ciò deve accadere. Se chiami più volte malloc()
per ottenere diversi pezzi della memoria , in generale non importa quale ordine chiami free()
quando hai finito con lo . Tuttavia, l'ordine è importante qui per un motivo specifico molto : si sta utilizzando una porzione di memoria malloc
per contenere i puntatori ad altri blocchi di memoria malloc
ed. Perché si must non tentativo di lettura o scrittura della memoria una volta che avete lo restituì con free()
, ciò significa che si sta andando ad avere per liberare i pezzi con loro puntatori memorizzati nel a[i]
prima si libera la a
stesso blocco. I singoli blocchi con puntatori memorizzati in a[i]
non dipendono da ciascun altro, e quindi possono essere free
d nell'ordine desiderato.
Così, mettendo insieme tutto questo, otteniamo questo:
for (i = 0; i < m; i++) {
free(a[i]);
}
free(a);
Un ultimo consiglio: quando si chiama malloc()
, pensare di cambiare questi:
int **a = malloc(m * sizeof(int *));
a[i]=malloc(n * sizeof(int));
a:
int **a = malloc(m * sizeof(*a));
a[i]=malloc(n * sizeof(*(a[i])));
Cosa sta facendo? Il compilatore sa che a
è un int **
, quindi può determinare che sizeof(*a)
è lo stesso di sizeof(int *)
. Tuttavia, se in seguito si cambia idea e vuole char
s o short
s o long
s o qualunque sia nella propria matrice, invece di int
s, o si adattano questo codice per dopo uso in qualcosa d'altro, si dovrà cambiare solo quello rimanente fa riferimento a int
nella prima riga sopra citata, e tutto il resto si posizionerà automaticamente per te. Ciò rimuove la probabilità di errori non notificati in futuro.
Buona fortuna!
Cavillo terminologico: questo non è ciò che C solitamente chiama "array multidimensionale". È solo l'unico modo per usare la sintassi 'a [i] [j]', pur consentendo a entrambe le dimensioni di essere sconosciute in fase di compilazione. L'altro tipo di matrice multidimensionale è una matrice di matrici, invece di questa matrice di puntatori a (i primi elementi di) matrici. –