How to dynamically allocate a 2D array in C? (original) (raw)

Last Updated : 10 Jan, 2025

Following are different ways to create a 2D array on the heap (or dynamically allocate a 2D array).
In the following examples, we have considered '**r' as number of rows, '**c' as number of columns and we created a 2D array with r = 3, c = 4 and the following values

1 2 3 4
5 6 7 8
9 10 11 12

**1) Using a single pointer and a 1D array with pointer arithmetic:
A simple way is to allocate a memory block of size r*c and access its elements using simple pointer arithmetic.

C `

#include <stdio.h> #include <stdlib.h>

int main(void) { int r = 3, c = 4;

int* ptr = malloc((r * c) * sizeof(int));

/* Putting 1 to 12 in the 1D array in a sequence */
for (int i = 0; i < r * c; i++)
    ptr[i] = i + 1;

/* Accessing the array values as if it was a 2D array */
for (int i = 0; i < r; i++) {
    for (int j = 0; j < c; j++)
        printf("%d ", ptr[i * c + j]);
    printf("\n");
}

free(ptr);

return 0;

}

`

Output

1 2 3 4 5 6 7 8 9 10 11 12

**2) Using an array of pointers
We can create an array of pointers of size r. Note that from C99, C language allows variable sized arrays. After creating an array of pointers, we can dynamically allocate memory for every row.

C `

#include <stdio.h> #include <stdlib.h>

int main() { int r = 3, c = 4, i, j, count;

int* arr[r];
for (i = 0; i < r; i++)
    arr[i] = (int*)malloc(c * sizeof(int));

// Note that arr[i][j] is same as *(*(arr+i)+j)
count = 0;
for (i = 0; i < r; i++)
    for (j = 0; j < c; j++)
        arr[i][j] = ++count; // Or *(*(arr+i)+j) = ++count

for (i = 0; i < r; i++)
    for (j = 0; j < c; j++)
        printf("%d ", arr[i][j]);

/* Code for further processing and free the
  dynamically allocated memory */

for (int i = 0; i < r; i++)
    free(arr[i]);

return 0;

}

`

Output

1 2 3 4 5 6 7 8 9 10 11 12

**3) Using pointer to a pointer
We can create an array of pointers also dynamically using a double pointer. Once we have an array pointers allocated dynamically, we can dynamically allocate memory and for every row like method 2.

C `

#include <stdio.h> #include <stdlib.h>

int main() { int r = 3, c = 4, i, j, count;

int** arr = (int**)malloc(r * sizeof(int*));
for (i = 0; i < r; i++)
    arr[i] = (int*)malloc(c * sizeof(int));

// Note that arr[i][j] is same as *(*(arr+i)+j)
count = 0;
for (i = 0; i < r; i++)
    for (j = 0; j < c; j++)
        arr[i][j] = ++count; // OR *(*(arr+i)+j) = ++count

for (i = 0; i < r; i++)
    for (j = 0; j < c; j++)
        printf("%d ", arr[i][j]);

/* Code for further processing and free the
   dynamically allocated memory */

for (int i = 0; i < r; i++)
    free(arr[i]);

free(arr);

return 0;

}

`

Output

1 2 3 4 5 6 7 8 9 10 11 12

**4) Using double pointer and one malloc call

C `

#include <stdio.h> #include <stdlib.h>

int main() { int r = 3, c = 4, len = 0; int *ptr, **arr; int count = 0, i, j;

len = sizeof(int*) * r + sizeof(int) * c * r;
arr = (int**)malloc(len);

// ptr is now pointing to the first element of the 2D
// array
// it points to the memory just after the row pointers
// allocated memory
ptr = (int*)(arr + r);

// for loop to point rows pointer to appropriate
// location in 2D array
for (i = 0; i < r; i++)
    arr[i] = (ptr + c * i);

for (i = 0; i < r; i++)
    for (j = 0; j < c; j++)
        arr[i][j]
            = ++count; // OR *(*(arr+i)+j) = ++count

for (i = 0; i < r; i++)
    for (j = 0; j < c; j++)
        printf("%d ", arr[i][j]);

return 0;

}

`

Output

1 2 3 4 5 6 7 8 9 10 11 12

**5) Using a pointer to Variable Length Array.

The dimensions of VLA are bound to the type of the variable. Therefore one form a pointer to an array with run-time defined shape.
The pointer has to be dereferenced before subscripting with syntax (*arr)[i][j].

C `

#include <stdio.h> #include <stdlib.h>

int main() { int row = 3, col = 4, i, j, count;

int (*arr)[row][col] = malloc(sizeof *arr);

count = 0;
for (i = 0; i < row; i++)
    for (j = 0; j < col; j++)
        (*arr)[i][j] = ++count;

for (i = 0; i < row; i++)
    for (j = 0; j < col; j++)
        printf("%d ", (*arr)[i][j]);

free(arr);

return 0;

}

`

Output

1 2 3 4 5 6 7 8 9 10 11 12

**6) Using a pointer to the first row of VLA

Similar to 5 but allows arr[i][j] syntax.

C `

#include <stdio.h> #include <stdlib.h>

int main() { int row = 3, col = 4, i, j, count;

int (*arr)[col] = calloc(row, sizeof *arr);

count = 0;
for (i = 0; i < row; i++)
    for (j = 0; j < col; j++)
        arr[i][j] = ++count;

for (i = 0; i < row; i++)
    for (j = 0; j < col; j++)
        printf("%d ", arr[i][j]);

free(arr);

return 0;

}

`

Output

1 2 3 4 5 6 7 8 9 10 11 12