2D Array

Initialisation

Inline initialisation

A 2D array can be initialise as follows:

char arr[][3] = {
    {'a', 'b', 'c'},
    {'d', 'e', 'f'},
    {'g', 'h', 'k'},
};

Or we can specify the size

char arr[][3] = {
    {'a', 'b', 'c'},
    {'d', 'e', 'f'},
    {'g', 'h', 'k'},
};

Memory structure

The memory structure in here will be different than in the malloc one. Since we declare as an array, it will be within 1 contiguous block.

Pasted image 20240707184209.png

With pointer working like this:

Pasted image 20240707210440.png

Malloc

We first need to malloc the array. And loop through and malloc each block of array:

char **arr = (char**) malloc(sizeof(char*) * 3);

for(int i =0; i < 3; i++) {
    arr[i] = malloc(sizeof(char*) * 3);
}

Memory structure

For the first line, we basically only malloc 3 pointers:

Pasted image 20240707183119.png

However, to assign the elements inside these pointers, we need to also malloc at each of the pointer:

Pasted image 20240707183138.png

And now we can fill the elements inside the blue one. After mallocing, this is how the structure memory works:

Pasted image 20240707183721.png

Subscripting

When selecting an element, following the same concept of Array supscripting, we have:

arr[2][1] = *(*(arr + 2) + 1)

Let's break it down:

  • arr[2] will select the value of p3 pointer.
    • Address of p3 is arr + 2. This pointer will store rvalue of memory address of arr[2]. Therefore it's *(arr + 2)
  • arr[2][1] will select the value of arr[2] + 1 pointer
    • From the above, we know that arr[2] will return the value of &arr[2][0] now if we have [1] it's simply just arr[2] + 1.
    • Which means it will be *(arr[2] + 1) or *(*arr + 2) + 1)

Memory visualiser

Malloc

Pasted image 20240708090707.png

Note that in here even though p3 (arr + 2) points to arr[2][0] directly. You cannot do *(arr + 2) to get arr[2][0] since the type is different. arr + 2 is pointing to the array representation type and we're trying to get the value of arr[2][0].

A way to bypass this is to cast *(arr + 2) to void* and try to read it as it: