I have initialized a 2D array like a 1D array:
int a[2][3] = {1,2,3,4,5}
How are the values stored in this array?
They are assigned as follows:
1 2 3
4 5 0
The zero is because you've allocated an array of size 6, but only specified 5 elements.
This is called "row-major order".
You may wish to formalize your code slightly. Your code is currently:
int a[2][3] = {1,2,3,4,5};
If you compile this with gcc main.c -Wall -pedantic --std=c99
, you'll get a few warnings:
temp.c:2:17: warning: missing braces around initializer [-Wmissing-braces]
Resolve this using
int a[2][3] = {{1,2,3,4,5}};
This will give you a new warning:
temp.c:2:25: warning: excess elements in array initializer
Resolve this using:
int a[2][3] = {{1,2,3},{4,5,0}};
This explicitly represents the data as having two rows of three elements each.
Some thoughts on memory layout
int a[2][3]
will produce an "array of arrays". This is similar to, but contradistinct from, an "array of pointers to arrays". Both have similar access syntax (e.g. a[1][2]
). But only for the "array of arrays" can you reliably access elements using a+y*WIDTH+x
.
Some code might clarify:
#include
#include
void PrintArray1D(int* a){
for(int i=0;i<6;i++)
printf("%d ",a[i]);
printf("\n");
}
int main(){
//Construct a two dimensional array
int a[2][3] = {{1,2,3},{4,5,6}};
//Construct an array of arrays
int* b[2];
b[0] = calloc(3,sizeof(int));
b[1] = calloc(3,sizeof(int));
//Initialize the array of arrays
for(int y=0;y<2;y++)
for(int x=0;x<3;x++)
b[y][x] = a[y][x];
PrintArray1D(a[0]);
PrintArray1D(b[0]);
}
When you run this, you get:
1 2 3 4 5 6
1 2 3 0 0 0
Printing b
gives zeros (on my machine) because it runs into uninitialized memory. The upshot is that using contiguous memory allows you to do handy things, let set all of the values without needing a double loop.