C – Two Dimensional Array Functions

Today, we’re going to take a look into the different ways by which we can make a function that returns a two dimensional array in C. To understand why these implementations work, we will need a little bit of insight as to what goes on behind the scenes when we are using two dimensional arrays in our C programs. 

Simply put, there is no easy way to have a function return a two dimensional array in C. Familiar syntax, such as that of Java,

public int[][] foo(int x){

or Python,

def foo(row, col){
    x = [[foo for i in range(col)] for j in range(row)]
    return x;

might lead you to believe that a similar result can be achieved in your code; unfortunately, this is not the case. Unlike in Java and Python, in arrays are not first class citizens. This means that they cannot be used in all the same contexts in which the average variable can. Let’s see how a function with a similar effect is achieved in C,

Don’t let the clutter of syntax intimidate you. If we look at it one line at a time, the function becomes much more manageable. For starters, let’s look at: 

int **return_arr(int num_row, int num_col){ ...

What does this mysterious return type int** mean? Well, we’ve seen that the name of an array is actually a pointer to the first element of the array. For example,

/* Initialize an array with two elements */ 
int arr[] = {0, 1}; 

/* The following variables are equivalent */
int x = arr[1];
int y = (*arr + 1); 

if ( y == x ){
    printf("arr[1] is identical to (*arr + 1)");

In-fact, you could replace the first line in the code above with,

int *arr = {0, 1};

and it would have no affect at all. It follows naturally then that int**, which is a pointer to a pointer (* is syntax for pointer), is equivalently a two dimensional array. Next we need to consider what these malloc lines are all about,

int **two_dim_arry =  (int **) malloc (sizeof(int *)*num_row);

This line is essentially saying “Hey computer, I’m going to store num_row arrays into my two_dim_arry, so I need you to reserve that memory for me”. This becomes even clearer upon inspecting,

int **two_dim_arry[i] =  (int *) malloc (sizeof(int )*num_col);

Roughly translating into, “Hey computer, I am going to store num_col integers in this array, so I need you to reserve num_col times sizeof(int) space for me.” But now that we told our computer to reserve that space, what happens when we don’t need it anymore?

Well, it turns out another function is needed,

Fortunately enough, this one is much more straightforward. It simply tells the computer that **arr has served its purpose and no longer needs the memory you reserved for it. This allows the computer to free up that memory and use it for other tasks.

Finally, we need a main function that puts together everything that we’ve learned,

Congratulations! You can now work with two-dimensional arrays in your projects. If you have any questions about the tutorial, or suggestions for future content, please post them as a comment down below.