How to dynamically allocate a 1D and 2D array in c.

dynamic array in c

We can create both static and dynamic array in C. These arrays can be one dimensional or multiple dimensional. In statically allocated array problem is that we have to specify the size of the array before the compilation. So the problem is generated when we don’t know how much size of the array required ahead of time.

Go here for a quick introduction of the Array in C:  Brief introduction of Array

We can resolve these issues using dynamic memory allocation. The advantage of a dynamically allocated array is that it is allocated on the heap at runtime. The C language provides a library function to request for the heap memory at runtime.

In the below program, I am using malloc to allocate the dynamic memory for the 1D and 2D array.

Syntax of malloc in C

void * malloc (size_t size);
Parameters

size ==> This is the size of the memory block, in bytes.

Return Value:

Returns a pointer to the allocated memory, if enough memory is not available then it returns NULL.

 

1D array using the dynamic memory allocation in C

In the below example, I am creating a pointer to an integer and assign it heap memory. When memory is successfully assigned to the pointer then we can use this pointer as a 1D array and using the square braces “[]” we can access the pointer as like the statically allocated array. Let us see the below Image for better understanding.

dynamic allocation of array in c

Let’s see a program example,

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

#define FAIL 1
#define TRUE 0

int main(int argc, char *argv[])
{
    int *piBuffer = NULL; //pointer to integer
    int nBlock = 0; //Variable store number of block
    int iLoop = 0; //Variable for looping

    printf("\nEnter the number of block = ");

    scanf("%d",&nBlock); //Get input for number of block

    piBuffer = (int *)malloc(nBlock * sizeof(int));
    //Check memory validity
    if(piBuffer == NULL)
    {
        return FAIL;
    }
    //copy iLoop to each block of 1D Array
    for (iLoop =0; iLoop < nBlock; iLoop++)
    {
        piBuffer[iLoop] = iLoop;
    }
    //Print the copy data
    for (iLoop =0; iLoop < nBlock; iLoop++)
    {
        printf("\npcBuffer[%d] = %d\n", iLoop,piBuffer[iLoop]);
    }
    // free allocated memory
    free(piBuffer);
    return TRUE;
}

Output:

 

 

If you love online courses and want to learn C programming, you can check the below courses it will help.

 

 

2D array using the dynamic memory allocation

In C language like the 1D array, we can also create the 2D array using the dynamic memory allocation at runtime. In below, I am listing some generic steps to create the 2D array using the pointers.

Steps to creating a 2D dynamic array in C using pointer to pointer

  • Create a pointer to pointer and allocate the memory for the row using malloc().
int ** piBuffer = NULL;

piBuffer = malloc( nrows * sizeof(int *));
  • Allocate memory for each row-column using the malloc().
for(i = 0; i < nrows; i++)
{
    piBuffer[i] = malloc( ncolumns * sizeof(int));
}
  • If each row does not have the same number of columns then allocate memory for each row individually.
piBuffer[0] = malloc( ncolumns * sizeof(int));
piBuffer[1] = malloc( ncolumns * sizeof(int));


piBuffer[n] = malloc( ncolumns * sizeof(int));

 

Let’s see the below picture where I am creating a 5×5  2D array using the dynamic memory allocation.

dynamic array in c using malloc

When each row contain the same number of column

Here we have to call malloc function two times, one for the row and second for the column. You can see the example code, where we are calling malloc function two times.

Note: Every location in each row is a contiguous memory but it is not necessary every row at contiguous memory in heap.

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

#define FAIL 1

//Free Allocated memory
void freeAllocatedMemory(int **piBuffer, int nRow)
{
    int iRow = 0;
    for (iRow =0; iRow < nRow; iRow++)
    {
        free(piBuffer[iRow]); // free allocated memory
    }
    free(piBuffer);
}

int main(int argc, char *argv[])
{
    int **piBuffer = NULL; //pointer to pointer
    int nRow = 0; //variable store number of Row
    int nColumn = 0; //variable store number of Row
    int iRow = 0; //Variable for looping Row
    int iCol = 0; //Variable for looping column


    printf("\nEnter the number of Row = ");
    scanf("%d",&nRow); //Get input for number of Row

    printf("\nEnter the number of Column = ");
    scanf("%d",&nColumn); //Get input for number of Column

    //Allocate memory for row
    piBuffer = (int **)malloc(nRow * sizeof(int*));
    //Check memory validity
    if(piBuffer == NULL)
    {
        return FAIL;
    }

    //Allocate memory for column
    for (iRow =0 ; iRow < nRow ; iRow++)
    {
        piBuffer[iRow] = (int *)malloc(nColumn * sizeof(int));
        //Check memory validity
        if(piBuffer[iRow] == NULL)
        {
            freeAllocatedMemory(piBuffer,iRow);
            return FAIL;
        }
    }

    //Copy the data in 2d Array

    for (iRow =0 ; iRow < nRow ; iRow++)
    {
        for (iCol =0 ; iCol < nColumn ; iCol++)
        {
            piBuffer[iRow][iCol] = 3;
        }
    }

    //Print the content of 2D array
    for (iRow =0 ; iRow < nRow ; iRow++)
    {
        for (iCol =0 ; iCol < nColumn ; iCol++)
        {
            printf("\npiBuffer[%d][%d] = %d\n",iRow, iCol,piBuffer[iRow][iCol]);
        }
    }

    freeAllocatedMemory(piBuffer,nRow);

    return 0;
}

Output:

 

 

 

Note: You can see, how we can create a vector in C.

 

When each row contain a different number of column

We can also create a non-square two-dimensional array in c using the dynamic memory allocation. Here we have to explicitly call malloc for each row. Here we are lucky because the number of columns of each row is equal to their row_index+1. For example, the 0th row has 1 column, 1st row has 2 columns ..etc. So we are able to use for loop to call the malloc function. It reduces the code length.

Consider the below image and example for better understanding.

2d array in c using pointers

 

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

#define FAIL 1

//Free Allocated memory
void freeAllocatedMemory(int **piBuffer, int nRow)
{
    int iRow = 0;
    for (iRow =0; iRow < nRow; iRow++)
    {
        free(piBuffer[iRow]); // free allocated memory
    }
    free(piBuffer);
}

int main(int argc, char *argv[])
{

    int **piBuffer = NULL; //pointer to pointer
    int nRow = 0; //variable store number of Row
    int iRow = 0; //Variable for looping Row
    int iCol = 0; //Variable for looping column


    printf("\nEnter the number of Row = ");
    scanf("%d",&nRow); //Get input for number of Row


    //Allocate memory for row
    piBuffer = (int **)malloc(nRow * sizeof(int*));
    //Check memory validity
    if(piBuffer == NULL)
    {
        return FAIL;
    }
    //Allocate memory for column
    for (iRow =0 ; iRow < nRow ; iRow++)
    {
        piBuffer[iRow] = (int *)malloc((iRow+1) * sizeof(int));
        //Check memory validity
        if(piBuffer[iRow] == NULL)
        {
            freeAllocatedMemory(piBuffer,iRow);
            return FAIL;
        }
    }
    //Copy the data in 2d Array
    for (iRow =0 ; iRow < nRow ; iRow++)
    {
        for (iCol =0 ; iCol <= iRow ; iCol++)
        {
            piBuffer[iRow][iCol] = 27;
        }
    }
    //Display the stored data
    for (iRow =0 ; iRow < nRow ; iRow++)
    {
        for (iCol =0 ; iCol <= iRow ; iCol++)
        {
            printf("\npiBuffer[%d][%d] = %d\n",iRow, iCol,piBuffer[iRow][iCol]);
        }
    }
    //Free Allocated memory
    freeAllocatedMemory(piBuffer,iRow);

    return 0;
}

Output:

 

 

 

 

 

 

 

 

 

Dynamically 2D array in C using the single pointer:

Using this method we can save memory. In which we can only do a single malloc and create a large 1D array. Here we will map 2D array on this created 1D array.

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

#define FAIL 1

int main(int argc, char *argv[])
{
    int *piBuffer = NULL; //pointer to integer
    int nRow = 0; //variable store number of Row
    int nColumn = 0; //variable store number of Row
    int iRow = 0; //Variable for looping Row
    int iCol = 0; //Variable for looping column

    printf("\nEnter the number of Row = ");
    scanf("%d",&nRow); //Get input for number of Row

    printf("\nEnter the number of Column = ");
    scanf("%d",&nColumn); //Get input for number of Column

    //Allocate memory for row
    piBuffer = (int *)malloc(nRow * nColumn * sizeof(int));
    //Check memory validity
    if(piBuffer == NULL)
    {
        return FAIL;
    }
    //Copy 5 in 2d Array
    for (iRow =0 ; iRow < nRow ; iRow++)
    {
        for (iCol =0 ; iCol < nColumn ; iCol++)
        {
            piBuffer[iRow * nColumn + iCol] = 5;
        }
    }
    //Print the content of 2D array
    for (iRow =0 ; iRow < nRow ; iRow++)
    {
        for (iCol =0 ; iCol < nColumn ; iCol++)
        {
            printf("\npiBuffer[%d][%d] = %d\n",iRow, iCol,piBuffer[iRow * nColumn + iCol]);
        }
    }
    
    //free the allocated memory
    free(piBuffer);
    
    return 0;
}

Output:

 

 

 

 

 

You want to learn more about C Pointers, you can check the below articles.


34 comments

  1. thank you for your great efforts but i have a question i can not understand this line piBuffer[iRow * nColumn + iCol] in method 2 , thanks in advance .

    1. Thanks, in method 2 I have allocated a single block of memory but accessing it in row and column. In the below statement suppose nRow and nColumn are 3.

      for (iRow =0 ; iRow < nRow ; iRow++) { for (iCol =0 ; iCol < nColumn ; iCol++) { piBuffer[iRow * nColumn + iCol] = 5; } } When control comes first time in the inner loop, iRow will zero and nColumn is 3, so their multiplication will zero. So piBuffer[0 + iCol] and inner loop will execute till iCol is less than nColumn(3). When again control comes 2nd times in inner loop then iRow will 1, so multiplication of iRow and nColumn becomes 3 and piBuffer[3 + iCol]. This process continues till iRow less then nRow(3).

Leave a Reply

Your email address will not be published. Required fields are marked *