["Followup-To:" header set to comp.lang.c.]
On 2005-02-03,
<> wrote:
> All this time I was under the illusion that I understand the concept of
> multi-dimensional arrays well ---- however the following code snippet
> belies my understanding.
>
> I had assumed all along that a declaration like:
> int intArray[3][5]
> means that there is an array of pointers to int with a size of 5, each
> of whose elements is an array of int with a size of 3.
>
> This definition seemed intuitive to me since a declaration like
> int intVar[5]
> means that there is an array of integers with a size of 5.
In C multi-dimensioned arrays are arrays of arrays. With the above
declarations, intVar in an expression is treated as pointer to an int.
Similarily, intArray in an expression is treated as a pointer to an
array of 5 ints.
> In my "intuitive" thinking, to dynamically create a 2D array with 3
> rows and 5 columns, we would do the following:
>
> Allocate memory for 5 pointers to int (i.e. pointer array)
> For each entry in the pointer array
> Do
> Allocate memory for 3 ints
> Done
In C arrays are stored row-wise; the rightmost subscript varies the
fastest. If the rightmost dimension is 5, you need to allocte memory
for 5 ints for each occurrence of the next dimension to the left.
To the designers of C to dynamically create a 2D array with 3 rows
and 5 columns, you could use
int (*intArray_p)[3][5] = malloc(sizeof(*intArray_p));
to declare and allocate the array and use (*intArray_p)[i][j] to refer
to the i-th, j-th element.
If you know all but the leftmost dimension at compile time, you could
use
int (*intArray_p)[][5] = malloc(leftDimCount*sizeof(**intArray_p));
to declare and allocate the array and use (*intArray_p)[i][j] to refer
to the i-th, j-th element.
If you know neither of the dimensions at compile time, you could
use
int *int_p = malloc(leftDimCount*rightDimCount*sizeof(*int_p));
to declare and allocate the array and use int_p[i*rightDimCount + j]
to refer to the i-th, j-th element.
> My code had a bug, which was fixed by switching my logic to something
> like this (as can be seen from the coding example):
>
> Allocate memory for 3 pointers to int (i.e. pointer array)
You want to allocate memory for 3 pointers arrays of 5 ints. However,
in most implementations a pointer to int and a pointer to and array of
5 ints have the same representation.
> For each entry in the pointer array
> Do
> Allocate memory for 5 ints
> Done
>
> This indicates to me that the correct interpretation of a declaration
> like:
>
> int intArray[3][5]
>
> is that there is an array of pointers to int with a size of 3, each of
> whose elements is an array of int with a size of 5. Is this a correct
> interpretation? This sounds counter intuitive to me (for reasons
> mentioned above) but I have reconciled to this interpretation. I will
> jump off the cliff if I am wrong again!
The correct interpretation is that there is an array of 3 elements, each
of whose elements is an array of 5 ints. When intArray appears in an
expression, it is treated as a pointer to its first element, which is
and array of 5 ints. However, intArray is not stored as an array of
pointers.
[snip]