Dynamic Memory Allocation in C Programming Language
Dynamic memory allocation in C Introduction:
We have looked at the Strings and Pointers in earlier articles. In today’s article, We will look at the dynamic memory allocation in c programming language. How to allocate the memory dynamically in C and how to free the memory with example programs. So let’s get started.
📢 This program is part of the C Language Tutorial Series.
Static Memory Allocation in C:
So far we have used static memory allocation to create variables, arrays, strings, etc.
Why it is called static memory allocation? Because we need to specify the exact size of the array or string during the variable creation and we can’t modify the size during the program execution.
For example, you have an array of students’ IDs. We don’t know how many students are in the school, So we go ahead and create an array with a size 500 hoping it will hold all student’s details.
int students[500];
Now the array can hold at max 500 elements (Student details), It is fixed and we can’t change the array size during the program execution (Runtime).
What if the array size 500 is very small and we have around 10000 students in the school, Then the array won’t be in the position to hold the details of all students.
Similarly, What if the array size is very large and we have only 100 students in the school, Then we are wasting a lot of memory(RAM).
In both cases, The fixed size of the array is causing the problems. To overcome these problems, We use dynamic memory allocation in C language.
Recommended Reading:
Dynamic Memory Allocation in C Programming Language:
The process of allocating and de-allocating the memory during the program execution or runtime is called Dynamic Memory Allocation.
The C programming language supports dynamic memory allocation and it exposes a few library functions to allocate and de-allocate the memory during the runtime.
Unlike other variables, The dynamically allocated memory is stored in the Heap section of the RAM(Program Memory).
📢Remember to free the allocated memory properly. Otherwise, It will cause memory leaks.
We can allocate the memory using functions like malloc(), calloc(), and realloc(). Similarly, We can de-allocate the memory using the free() function in C language. All these functions are available as part of the stdlib.h header file.
Let’s look at the above functions in detail.
The malloc() function in C – Dynamic memory allocation in C using malloc() function:
The malloc() function is used to dynamically allocate memory in C Language. It takes size as an argument and allocates the specified number of bytes in the heap.
Here is the prototype of the malloc function in c
1 |
void *malloc(size_t size); |
The size_t is an unsigned integer type. So The malloc() function allocates the size number of bytes and returns a pointer to the allocated block of memory. The returned pointer is a void pointer, so we need to typecast it to the appropriate data type before using it.
If for any reason malloc() is not able to allocate the given number of bytes, Then it will return NULL character.
The malloc() function is declared in the stdlib.h header file. so don’t forget to include the stdlib.h header file in your program.
📢malloc – memory allocation – Allocates a contiguous block of memory in the heap section.
Let’s look at the syntax and example of the malloc() function in c programming.
Syntax of malloc() function:
1 |
pointer_name = (data_type *) malloc (size); |
Here
- pointer_name is the pointer name – This pointer_name will be pointing to the first block of allocated memory.
- (data_type *) is the typecast operation, As malloc returns a void pointer.
- size is the number of bytes malloc need to allocate.
Example Usage of malloc() function in c:
Let’s allocate the 40 Bytes of memory using malloc() function.
1 |
int *iPtr = (int *) malloc(40); |
If the above call to the malloc() function is successful, Then the malloc() function will allocate 40 Bytes of memory in the HEAP section and The starting address of the allocated memory will be stored in the iPtr pointer variable.
If the malloc() is not able to allocate the 40 Bytes in the Heap, Then the iPtr will have the NULL value. So it is always recommended to check the pointer variable( iPtr) to check the status of the memory allocation ( use if statement like below).
1 2 3 4 5 6 7 8 9 |
int *iPtr = (int *) malloc(40);  if( iPtr == NULL) {     // Memory not allocated     printf("ERROR! malloc() Failed Allocate the Memory\n"); }  // Memory is allocated. |
We can accommodate 10 integer variables in the 40 Bytes of memory (assuming 4 Bytes for each integer)
We can also use the sizeof() operator to properly allocate the memory. For example, If you want to allocate memory for 90 integers, Then you can pass sizeof(int) * 90 to the malloc() function.
1 2 3 4 5 6 7 |
int *iPtr = (int *) malloc ( sizeof(int) * 90 );  if( iPtr == NULL) {     // Memory not allocated     printf("ERROR! malloc() Failed Allocate the Memory\n"); } |
Example 1: Program to understand the malloc() function in C language:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
/*     Program to allocate memory using malloc() function     sillycodes.com */  #include <stdio.h> #include <stdlib.h>  int main() {     int numInt;      printf("Enter the number of integers you want to generate dynamically: ");     scanf("%d", &numInt);      int *iPtr;      iPtr = (int *) malloc(numInt * sizeof(int));      // check iPtr     if(iPtr == NULL)     {         printf("ERROR! Failed to Allocate Memory\n");         return 0;     }      printf("SUCCESS! Memory allocated successfully\n");      // free the memory before returning.     free(iPtr);      return 0; } |
We have used the malloc() function to dynamically allocate the memory for the integers. The program prompts the user to provide a number and stores it in numInt variable. Then it allocates the memory for numInt number of integers in Heap using the malloc() function.
1 |
iPtr = (int *) malloc(numInt * sizeof(int)); |
The malloc() function allocates the memory and returns a void pointer. As we are going to store the integers, We need to typecast the pointer to the integer pointer.
Finally, We are checking the pointer value iPtr and printing the result on the console.
📢We also used the free() function to free the dynamically allocated memory. We will look at the free() function in detail in the next sections of this post.
Program Output:
Let’s compile and run the program using your favorite compiler.
1 2 3 4 5 |
$ gcc malloc.c $ ./a.out Enter the number of integers you want to generate dynamically: 10 SUCCESS! Memory allocated successfully $ |
As we can see from the above output, The malloc() function is able to allocate the memory successfully.
Example 2: Allocate memory dynamically using malloc() function in C language:
Let’s create a program that takes and prints the user-supplied dynamic number of integers on the console.
For example, the user may want 5 integers, 10 integers, or 1000 integers, so we must create memory dynamically based on the user input(number of integers) and then take the integer numbers from the user and print them on the console.
Here is the program to dynamically create integer variables using the malloc() function.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
/*     Program to allocate memory using malloc() function     sillycodes.com */  #include <stdio.h> #include <stdlib.h>  int main() {     int numInt, i;      printf("Enter the number of integers you want to generate dynamically: ");     scanf("%d", &numInt);      int *iPtr;      iPtr = (int *) malloc(numInt * sizeof(int));      // check iPtr     if(iPtr == NULL)     {         printf("ERROR! Failed to Allocate Memory\n");         return 0;     }      printf("SUCCESS! Memory allocated successfully\n");         // Take the use input and update the integers     for(i = 0; i<numInt; i++)     {         printf("Enter an Integer: ");         scanf("%d", iPtr+i);     }      // print the values     printf("Entered Integers are : ");     for(i = 0; i<numInt; i++)     {         printf("%d ", iPtr[i]);    // we can also use *(iPtr+i)     }     // new line     printf("\n");      // free the memory before returning.     free(iPtr);      return 0; } |
The program allocates memory for the numInt integers, As the malloc() allocated memory, is a contiguous block of memory, We used a for loop to iterate over the memory block and updated it with user-provided values. Then, We used the iPtr+i to get the address of the memory location. Where i is the index and iPtr is the pointer returned by the malloc() function.
Finally, We used another for loop to display the values, We utilized the pointer subscript notation to get the value of the integer through the pointer variable iPtr. – iPtr[i]
Program Output:
Compile and Run the program using the C compiler.
Test 1:
1 2 3 4 5 6 7 8 9 10 11 |
$ gcc create-int-dynamic.c $ ./a.out Enter the number of integers you want to generate dynamically: 5 SUCCESS! Memory allocated successfully Enter an Integer: 77 Enter an Integer: 99 Enter an Integer: 43 Enter an Integer: 76 Enter an Integer: 29 Entered Integers are : 77 99 43 76 29 $ |
As we can see from the above output, The program is able to allocate the memory for the 5 Integer variables using malloc function.
Test 2:
In this example, We have dynamically allocated memory for 10 Integer variables using the malloc() function.
The calloc() function in C Programming – Allocate Blocks of memory dynamically:
The calloc() function is used to allocate multiple chunks of memory dynamically in C Programming Language. Here is the syntax of the calloc() function.
Syntax of calloc() function in C:
1 |
void *calloc(size_t n_chuncks, size_t size); |
Here
- n_chunks is the number of chunks or blocks
- size is the size of each chunk.
So the calloc() function allocates the n_chunks and the size of each chunk is size
Let’s look at an example
Allocate memory using calloc() function in C:
1 2 3 |
int p;  p = (int *) calloc (10,  sizeof(int) ); |
In the above example, We are allocating the 10 blocks of memory and each block of 4 Bytes size. (Assuming integer size is 4 Bytes). So in total, we are allocating the 40 Bytes, that can accommodate for the storage of ten integer variables.
Similar to the malloc() function, the calloc() function also returns NULL if it is failed to allocate the memory. So please check the pointer value before using it.
Program to Allocate memory dynamically using the calloc() function in C Language:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
/*     Program to allocate memory using calloc() function     sillycodes.com */  #include <stdio.h> #include <stdlib.h>  int main() {     int nChunks, i;      printf("How many integers you want to store: ");     scanf("%d", &nChunks);      int *ptr;      // call calloc() function     ptr = (int *) calloc(nChunks, sizeof(int));      // check pointer     if(ptr == NULL)     {         printf("ERROR! Failed to Allocate Memory\n");         return 0;     }      printf("SUCCESS! Memory allocated successfully using calloc() function\n");      // Take the use input and update the integers     for(i = 0; i<nChunks; i++)     {         // use scanf to store the data         printf("Enter a Number: ");         scanf("%d", ptr+i);     }      // print the integers     printf("Entered Integers are : ");     for(i = 0; i<nChunks; i++)     {         printf("%d ", *(ptr+i) );    // we can also use ptr[i]     }     // new line     printf("\n");      // free the memory.     free(ptr);      return 0; } |
Initially, the program prompts the user to provide the number of blocks or chunks and stores in the nChunks variable. Then it will use the calloc() function to create the nChunks memory dynamically, where each chunk is equal to the sizeof the integer variable.
1 |
ptr = (int *) calloc(nChunks, sizeof(int)); |
Once the memory is allocated, We update the memory blocks with the user-provided data. We use a for loop to traverse through the memory.
1 2 3 4 5 6 7 |
// Take the use input and update the integers for(i = 0; i<nChunks; i++) {     // use scanf to store the data     printf("Enter a Number: ");     scanf("%d", ptr+i); } |
Finally, We display the provided numbers on the console using another for loop.
Program Output – Calloc() to allocate memory:
Compile and Run the program using GCC compiler (Any compiler)
1 2 3 4 5 6 7 8 9 10 11 12 13 |
$ gcc calloc.c $ ./a.out How many integers you want to store: 7 SUCCESS! Memory allocated successfully using calloc() function Enter a Number: 8 Enter a Number: 9 Enter a Number: 54 Enter a Number: 12 Enter a Number: 48 Enter a Number: 98 Enter a Number: 42 Entered Integers are : 8 9 54 12 48 98 42 $ |
As we can see from the above output, The calloc() function successfully allocated the requested 7 Integers memory dynamically.
What are the differences between the malloc and calloc functions in C:
Firstly, we can see the syntactical difference. The malloc() function takes only one argument, while the calloc() function takes two arguments.
malloc() function syntax:
1 |
ptr = (int *) malloc(size); |
calloc() function syntax:
1 |
ptr = (int *) calloc(nChunks, size); |
One more difference is, The memory blocks allocated by the calloc() function are initialized with zeros. While the malloc() allocated memory contains the garbage values.
The realloc() function in C programming – Re-Allocate dynamically allocated memory:
As previously mentioned, The malloc() and calloc() functions are used to allocate memory, but what if you wish to modify the size of the dynamically allocated memory? This is where we use the realloc() function in the c language.
The realloc() function is used to reallocate the memory allocated by the malloc() or calloc() functions. We can decrease or increase the size of the dynamically allocated memory using the realloc() function in c. The realloc() function resizes the memory block while retaining the previous data.
Syntax of realloc() function in C language:
1 |
void *realloc(void *ptr, size_t size); |
Here
- ptr – Pointer to dynamically allocated memory( malloc() or calloc() allocated memory).
- size – New size of the memory block. It can see less than or greater than the previous size.
- void * – The realloc() function also returns the void pointer.
The realloc() function returns the pointer to the newly allocated memory block on successful reallocation. If the realloc() fails, It will return the NULL.
Example usage of realloc() function in C Programming:
Let’s say we want to dynamically allocate memory for 5 integer numbers.
1 2 3 |
int rPtr; Â rPtr = (int *) malloc ( 5 * sizeof(int) ); |
Here we used the malloc() function to allocate the memory for 5 integer variables. The rPtr pointer variable is storing the address of the first memory byte.
Now, our requirement is changed and we need to increase the dynamically allocated memory to store the 10 integers variables.
We can use the realloc() function to resize the dynamically allocated memory.
1 |
rPtr = (int *) realloc( rPtr, 10 * sizeof(int) ); |
We passed the new size 10 * sizeof(int) to the realloc() function along with the pointer variable rPtr
The realloc() function resizes the memory and returns a pointer to the newly allocated memory block, The returned pointer is a void pointer, So we need to typecast it to the appropriate pointer type.
Quick Notes on realloc() function in C Language:
- On successful resize of memory, The realloc() function returns the pointer to the newly allocated memory block. If realloc() function fails, It will return the NULL value.
- The address of the pointer variable rPtr(Returned by the realloc() function) might change if there is not sufficient memory at the previous address. In such cases, The realloc() function moves the data to a new block of memory and returns the pointer to the newly allocated memory block. So we might get a different pointer address.
- The newly allocated memory bytes are uninitialized so they might contain garbage values.
Let’s look at a program to reallocate dynamically allocated memory using realloc() function in c programming language.
Resizing the dynamically allocated memory using realloc() function in C programming language:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
/*     Program to resize memory using realloc() function in c programming     sillycodes.com */  #include <stdio.h> #include <stdlib.h>  int main() {     int size, i;      printf("Enter the number of integers you want to store dynamically: ");     scanf("%d", &size);      int *rPtr;      rPtr = (int *) malloc(size * sizeof(int));      // check rPtr     if(rPtr == NULL)     {         printf("ERROR! malloc() - Failed to Allocate Memory\n");         return 0;     }      printf("SUCCESS! Memory allocated successfully\n");     printf("Please provide integers to store\n");      // Take the use input and update the integers     for(i = 0; i<size; i++)     {         printf("Enter an Integer: ");         scanf("%d", rPtr+i);     }      // print the values     printf("Entered Integers are : ");     for(i = 0; i<size; i++)     {         printf("%d ", rPtr[i]);    // we can also use *(rPtr+i)     }     // new line     printf("\n");      // resize     int newSize;     printf("RESIZE: Please provide new size : ");     scanf("%d", &newSize);      // call 'realloc' to resize     rPtr = (int *) realloc( rPtr, newSize * sizeof(int) );      // update the resized array     if(newSize > size)     {         printf("Provide values for remaining integers\n");             for(i = size; i<newSize; i++)         {             printf("Enter an Integer: ");             scanf("%d", rPtr+i);         }     }      // print the resized numbers     // print the values     printf("Entered Integers are : ");     for(i = 0; i<newSize; i++)     {         printf("%d ", rPtr[i]);    // we can also use *(rPtr+i)     }     // new line     printf("\n");      // free the memory before returning.     free(rPtr);      return 0; } |
Program Output:
We started the above program by dynamically allocating memory for a user-provided number of integer variables using the malloc() function. If the malloc() failed to allocate the memory, Then we terminated the program using a return statement. Otherwise, it will continue and prompt the user to provide the values for each integer variable using a for loop and store the values in the allocated memory. We then printed the integer variable on the console using another for loop.
Next, We prompted the user to provide the new size and reallocated the dynamically allocated memory using the realloc() function. To reallocate memory we need to pass the pointer variable and the new size to the realloc() function. like below
1 |
rPtr = (int *) realloc( rPtr, newSize * sizeof(int) ); |
If the new size is greater than the old size. Then we prompted the user to provide the remaining values and displayed them on the screen.
Finally, We freed the allocated memory using the free() function.
Program Output:
Compile the program
gcc realloc-ex.c
Run the program.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
$ ./a.out Enter the number of integers you want to store dynamically: 5 SUCCESS! Memory allocated successfully Please provide integers to store Enter an Integer: 10 Enter an Integer: 20Â Â Enter an Integer: 30 Enter an Integer: 40 Enter an Integer: 50 Entered Integers are : 10 20 30 40 50 RESIZE: Please provide new size : 9 Provide values for remaining integers Enter an Integer: 60 Enter an Integer: 70 Enter an Integer: 80 Enter an Integer: 90 Entered Integers are : 10 20 30 40 50 60 70 80 90 $ |
As we can see from the above output, We reallocated the memory to store 9 Integers(From 5 Integers) using the realloc() function.
The free() function in C – Release/Free the dynamically allocated memory:
The free() function is used to free the dynamically allocated memory in C programming. As we already know, The dynamically allocated memory won’t be freed by the compiler(Except few cases), It is the programmer’s responsibility to properly free the dynamically allocated memory. So Once we finished using the dynamically allocated variables, arrays, etc, Then it is a good idea to free them using the free() function.
📢 Once the program terminates, Dynamically allocated memory will be released (Even if you forgot to free() in your program).
Syntax of free() function in C Language:
1 |
void free(pointer_name); |
Example usage of free() Function – Free memory:
1 |
free(ptr);Â Â Â Â Â Â Â Â // ptr is pointer pointing to dynamically allocated memory |
Here pointer variable ptr is pointing to the dynamically allocated memory address (Allocated using the malloc() or calloc() functions).
The free() function doesn’t return anything, So the return type of the free function is void
Let’s look at a program to understand the free() function.
Program to understand the use of free() function in C Language:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
/*     Program to allocate memory using malloc() function     sillycodes.com */  #include <stdio.h> #include <stdlib.h>  int main() {     int size, i;      printf("Enter size of memory block: ");     scanf("%d", &size);      int *iPtr;      iPtr = (int *) malloc(size * sizeof(int));      // check iPtr     if(iPtr == NULL)     {         printf("ERROR! Failed to Allocate Memory\n");         return 0;     }      printf("SUCCESS! Memory allocated successfully\n");      // Do the work         // free the memory.     free(iPtr);     printf("Memory Released!\n");      return 0; } |
In the above program, We have allocated the size * sizeof(int) bytes of memory using the malloc() function. Once we performed the necessary tasks, we no longer need the allocated memory. So we can release the dynamically allocated memory using free() function.
1 |
free(iPtr); |
We called the free() function with the pointer variable iPtr to release or free the memory so that it can be allocated to other programs.
📢 The free() function de-allocates the memory and it can be reused by any other program.
Program Output:
Let’s compile and Run the Program and observe the log messages.
1 2 3 4 5 6 |
$ gcc free.c $ ./a.out Enter size of memory block: 20 SUCCESS! Memory allocated successfully Memory Released! $ |
As you can see from the above output, We are able to properly free/release the dynamically allocated memory using the free() function in c language.
What happens if doesn’t release dynamically allocated memory?
It is always recommended to free the dynamically allocated memory. If we forgot to free the dynamically allocated memory, It will cause a memory leak.
When the program stops all the dynamically allocated memory will be released, But if you are program is a long-running process like an operating system, web server, or any application server, Then we can observe the memory leak (slow growth of memory usage). So we should always free the dynamically allocated memory to avoid the memory leak.
One more thing to note, Even if your pointer variable is a local variable ( inside the function), Compiler won’t free the dynamically allocated memory. ( Since it will be stored in the HEAP section, So it will only be freed on program termination )
1 2 3 4 5 6 |
int doingStuff(int data) {   int *ptr = (int *) malloc(1000 * sizeof(int));   ....   ....  // not releasing memory } |
In the above example, The ptr is a local variable that is pointing to a memory address in the HEAP section. As we are not using the free() function inside the doStuff function, When the doStuff function returns dynamically allocated memory won’t be released. So use the free(ptr) to free the dynamically allocated memory.
📢 Finding memory leaks is a time-consuming operation, Thus try to free() the memory after use.
FAQ on Dynamic memory allocation in C:
The process of allocating and de-allocating the memory during the program execution or runtime is called Dynamic Memory Allocation.
The malloc(), calloc() are used to allocate the memory dynamically. The realloc() function is used to re-allocate i.e increase or decrease the dynamically allocated memory.
The free() function is used to release the dynamically allocated memory in C language.
Firstly, we can see the syntactical difference. The malloc() function takes only one argument, while the calloc() function takes two arguments. One more difference is, The memory blocks allocated by the calloc() function are initialized with zeros. While the malloc() allocated memory contains the garbage values.
It is always recommended to free the dynamically allocated memory. If we forgot to free the dynamically allocated memory, It will cause a memory leak. When the program stops all the dynamically allocated memory will be released, But if you are program is a long-running process like an operating system, web server, or any application server, Then we can observe the memory leak (slow growth of memory usage). So we should always free the dynamically allocated memory to avoid the memory leak.
Related C Tutorials:
- C Tutorials Index
- C Programs Index – 300+ Programs
- Call by Value and Call by Address / Call by Reference in C Langauge
- Recursion in C Language with Example Programs and Call Flow
- Local Variable and Global Variables in C
- Program to Add Two Numbers using Pointers in C
- Program to perform Arithmetic Operations using Pointers in C
- Swap Two Numbers using Pointers in C Language
- Accessing Array elements using pointers in C language
- Print the string elements using pointers in C Language