Basta calcolare la quantità totale di memoria necessaria per entrambe le nrows
fila punti, ei dati effettivi, aggiungere il tutto, e fare una sola chiamata:
int **array = malloc(nrows * sizeof *array + (nrows * (ncolumns * sizeof **array));
Se pensi che questo sembra troppo complesso, è possibile dividerlo e renderlo un auto-documentazione po nominando i diversi termini dell'espressione dimensioni:
int **array; /* Declare this first so we can use it with sizeof. */
const size_t row_pointers_bytes = nrows * sizeof *array;
const size_t row_elements_bytes = ncolumns * sizeof **array;
array = malloc(row_pointers_bytes + nrows * row_elements_bytes);
È quindi necessario passare attraverso e inizializzare la riga puntatori in modo che i punti di puntatore di ogni fila al primo elemento di quella particolare fila:
size_t i;
int * const data = array + nrows;
for(i = 0; i < nrows; i++)
array[i] = data + i * ncolumns;
si noti che la struttura risultante è sottilmente diverso da quello che si ottiene se si fa ad esempio int array[nrows][ncolumns]
, perché abbiamo puntatori di riga espliciti, il che significa che per un array allocato in questo modo, non esiste un vero requisito che tutte le righe abbiano lo stesso numero di colonne.
Significa anche che un accesso come array[2][3]
fa qualcosa di diverso da un accesso di aspetto simile in un vero array 2d. In questo caso, l'accesso più interno viene eseguito per primo e array[2]
legge un puntatore dal terzo elemento in array
. Quel puntatore è quindi trattato come la base di una matrice (colonna), nella quale indichiamo per ottenere il quarto elemento.
Al contrario, per qualcosa come
int array2[4][3];
quali è un "ricco" matrice 2D corretto occupare la pena di spazio soli 12 numeri interi, l'accesso come array[3][2]
rompe semplicemente verso il basso per l'aggiunta di un offset alla base indirizzo per ottenere l'elemento.
+1: meglio del mio, senza colatura :) – Necrolis
@Unwind posso avere una vista pittorica della memoria per questa soluzione che aiuta nei dettagli di alta qualità per capire questo codice. –
@AmitSinghTomar: Non penso di poterlo rappresentare chiaramente in ASCII e non ho il tempo di disegnare qualcosa in un vero programma di grafica al momento, mi dispiace. Forse qualcuno può intervenire? :) – unwind