Multi-dimensional arrays can be built dynamically using
pointers-to-pointers with malloc. In the example below, a single
pointer-to-pointer-to-int is declared. Upon declaration, the
pointer has no meaningful value. A call to mallac then requests
that the pointer point to a block of nx valid memory units:
x = (int **) malloc(nx * sizeof(int *));
After this call, x now has a valid value; specifically, the
beginning address of a block of memory which contains nx
pointers-to-int. Eachof these pointers to int is just a regular
pointer, as we have seen many times. They have yet to be
initialized to anything meaningful, and the can each be accessed
as either
x[0], x[1] ... x[nx-1], OR *x, *(x+1), *(x+2),
... *(x+nx-1).
To give eachof these pointers a meaningful value,
we can call malloc for each of them, such as is accomplished by
this loop:
for (i=0;i<nx;++i){
x[i] = ( int * ) malloc( ny * sizeof(int));
}
Note that we could have also said:
for (i=0;i<nx;++i){
*(x+i) = ( int * ) malloc( ny * sizeof(int));
}
Now that each pointer in our array of pointers points to a
meaningful block of memory (each of size ny ints), we can assign
values. To understand how values are assigned, consider the
schematic below. You will need to study this very carefully until
it is very clear what is going on. This can be a little tricky but
once you get the hang of it it's not so bad.
x[0] ---> | *x[0] | *x[0]+1 | *x[0] + 2 | ... | *x[0]+ny-1 |
x[1] ---> | *x[1] | *x[1]+1 | *x[1] + 2 | ... | *x[1]+ny-1 |
.
.
.
x[nx-1] ---> | *x[nx-1] | *x[nx-1]+1 | *x[nx-1] + 2 | ... | *x[nx-1]+ny-1 |
This is equivalent to:
x[0] ---> | *(*(x+0)+0) | *(*(x+0)+1) | *(*(x+0)+2) | ... | *(*(x+0)+ny-1) |
x[1] ---> | *(*(x+1)+0) | *(*(x+1)+1) | *(*(x+1)+2) | ... | *(*(x+1)+ny-1) |
.
.
.
x[nx-1] ---> | *(*(x+nx-1)+0) | *(*(x+nx-1)+1) | *(*(x+nx-1)+2) | ... | *(*(x+nx-1)+ny-1) |
And this is equivalent to:
x[0] ---> | x[0][0] | x[0][1] | x[0][2] | ... | x[0][ny-1] |
x[1] ---> | x[1][0] | x[1][1] | x[1][2] | ... | x[1][ny-1] |
.
.
.
x[nx-1] ---> | x[nx-1][0] | x[nx-1][1] | x[nx-1][2] | ... | x[nx-1][ny-1] |
... given the important relation:
*( *(x + i) + j) = *( x[i] + j) = x[i][j]