I have a question about the memory layout of a two-dimensional array.
When we define one, just like int a[3][4], is the memory allocated to this array continuous?
Or in other words, is a two-dimensional array implemented as a continuous one-dimensional array?
If the answer is yes, is accessing a[0][6] equivalent to accessing a[1][2]?
I wrote the following C program.
#include <stdio.h>
int main(){
int a[3][4] = {{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12}};
printf("%d %d\n", a[0][6], a[1][2]);
return 0;
}
I find that the output is 7 7.
a[0][6] seems illegal, but it points to a[1][2], I want to know why and is such operation legal?
This is as interesting case. Section 6.2.5p20 of the C standard defines an array as follows:
So an array is a contiguous set of objects of a particular type. In the case of
int a[3][4]it is an array of size 3 whose objects are also arrays. The type of the subarray isint [4], i.e. an array of size 4 of typeint.This means that a 2D array, or more accurately an array of arrays, does indeed have all of the individual members of the inner array laid out continuously.
This does not however mean that the above array can be accessed as
a[0][6]as in your example.Section 6.5.2.1p2 regarding the array subscript operator
[]states:And section 6.5.6p8 regarding the
+operator when applied to a pointer operand states:There's a lot to ingest here, but the important part is that given an array of size X, the valid array indices range from 0 to X-1, and attempting to use any other index triggers undefined behavior. In particular, since
a[0]has typeint [4], attempting to accessa[0][6]is going outside the bounds of the arraya[0].So while
a[0][6]in practice would probably work, the C standard makes no guarantee that it will. And given that modern optimizing compilers will aggressively assume undefined behavior doesn't exist in a program and optimize based on that fact, you could end up in a situation where something goes wrong and you don't know why.To summarize: yes 2D arrays are implemented that way, and no you can't access them like that.