Open In App
Related Articles

How to dynamically allocate a 2D array in C?

Improve
Improve
Improve
Like Article
Like
Save Article
Save
Report issue
Report
 

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 

Time Complexity : O(R*C),  where R and C is size of row and column respectively.
Auxiliary Space: O(R*C), where R and C is size of row and column respectively.
 
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 

Time Complexity: O(R*C) 

Here R and C is size of row and column respectively.

Auxiliary Space: O(R*C)

The extra space is used to store the elements of the matrix.

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 

Time Complexity: O(R*C)

Here R and C is size of row and column respectively.

Auxiliary Space: O(R*C)

The extra space is used to store the elements of the matrix.
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 in of 2D array
    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 

Time Complexity: O(R*C)

Here R and C is size of row and column respectively.

Auxiliary Space: O(R*C)

The extra space is used to store the elements of the matrix.
Thanks to Trishansh Bhardwaj for suggesting this 4th method.

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 

Time Complexity: O(R*C)

Here R and C is size of row and column respectively.

Auxiliary Space: O(R*C)

The extra space is used to store the elements of the matrix.

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 

Time Complexity: O(R*C)

Here R and C is size of row and column respectively.

Auxiliary Space: O(R*C)

The extra space is used to store the elements of the matrix.



Last Updated : 20 Feb, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads