Skip to content

Initializing a 2D array like a 1D array

An answer to this question on Stack Overflow.

Question

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?

Answer

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 <stdlib.h>
#include <stdio.h>
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.