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.
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.
- The C Programming Language in Action ( FREE Trial Available).
- C Programming For Beginners – Master the C Language.
- Pointers in C Programming – Master the C Language.
- Learning C with Dan Gookin ( FREE Trial Available).
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.
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.
#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.
- A brief description of the pointer in C.
- Dangling, Void, Null and Wild Pointers
- Function pointer in c, a detailed guide
- How to use the structure of function pointer in c language?
- Function pointer in structure.
- Pointer Arithmetic in C.
- void pointer in C.
- 10 questions about dynamic memory allocation.
- Memory Layout in C.
- 100 C interview Questions
- File handling in C.
- C format specifiers.