I always believed that in C :
int a[5][3]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
refers to an array of arrays and in memory fifteen contiguous blocks are stored but a[0]
is the pointer to a[0][0]
and a[1]
is the pointer to a[1][0]
and so on. So I thought it to be similar to be an array of pointers. What is the difference between them?
Arrays and pointers have a very curious and intimate relationship in C (and C++). In most contexts, if you have something that is an 'array of X', then it will be silently converted to a 'pointer to X' that points at the first element of the array.
Your belief that
int a[5][3];
creates an array of arrays is entirely correct. According to the declaration, it is an array of 5 arrays of 3 ints
and it occupies 15 contiguous integers in memory.
Where you go wrong is in believing a[0]
to be a pointer. In fact, a[0]
is the first sub-array of a
and is itself an array of 3 ints
. However, due to the curious relationship between pointers and arrays, the expression a[0]
is almost always converted to a pointer.
One of the major differences between an array of arrays and an array of pointers is in where the array elements reside. An array of arrays will always occupy a contiguous block of memory, but the pointers in an array of pointers will each refer to their own (often disjoint) blocks of memory.
Arrays and pointers loosely equate to the same thing. When you declare an array N long, you're allocating a block of memory N long (times the size of the value type) and returning the pointer to the first element. Expressions like arr[2]
then retrieve a value from that memory by counting forward from that first pointer. If you have an array of arrays, then all you're storing in the first one (in your a
array) is pointers to where the other arrays are stored. (That said, I believe they should be in a contiguous block as you said)
Does that help the explanation somewhat?
int a[5][3]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
This is a true two dimensional array: 15 int
sized locations have been set aside and the conventional rectangular subscript is used to find the element a[row][col]
int *b[5];
This is an array of pointers which allocate 5 pointers and is not initialized but a[3][2]
and b[3][2]
are both syntactically legal references to a single int.
Assuming that each element of b
does
point to a three-element array, then there will be 15 ints
set aside, plus five cells for the
pointers.
The important advantage of the pointer array is that the rows of the array may be of
different lengths. That is, each element of b
need not point to a three-element vector, some
may point to two elements, some to nine, and some to none at all.