Open In App
Related Articles

How to dynamically allocate a 2D array in C?

Improve Article
Improve
Save Article
Save
Like Article
Like
 

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.
Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above

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.


Whether you're preparing for your first job interview or aiming to upskill in this ever-evolving tech landscape, GeeksforGeeks Courses are your key to success. We provide top-quality content at affordable prices, all geared towards accelerating your growth in a time-bound manner. Join the millions we've already empowered, and we're here to do the same for you. Don't miss out - check it out now!

Last Updated : 20 Feb, 2023
Like Article
Save Article
Previous
Next
Similar Reads