๐Ÿ“˜ Dynamic Memory Allocation in C – malloc(), calloc(), realloc(), free() Explained with Examples, Programs, Viva & MCQs


๐Ÿง‘‍๐Ÿ’ป Introduction

In C programming, memory plays a very important role.

Till now, we have learned:

  • Arrays

  • Structures

  • Pointers

  • Unions

All of them use static memory allocation, where memory size is fixed at compile time.

But what if:

  • We don’t know the size of data in advance?

  • We need memory at runtime?

  • We want to resize memory later?

  • We want better control over memory usage?

๐Ÿ‘‰ That’s where Dynamic Memory Allocation (DMA) comes into the picture.

Dynamic Memory Allocation allows us to allocate memory at runtime using special functions.

๐Ÿ“Œ Think of stack memory like a small backpack you carry daily, and heap memory like a warehouse where you rent space only when needed.
Stack space is limited and temporary, while heap space is larger and flexible.


๐Ÿง  Types of Memory in C

There are mainly two types of memory:


1️⃣ Stack Memory

  • Automatically allocated

  • Used for local variables

  • Fast access

  • Limited size

  • Destroyed when function ends

Example:

int x = 10; // Stored in stack memory

2️⃣ Heap Memory

  • Manually allocated

  • Used for dynamic memory allocation

  • Larger memory space

  • Must be freed manually

  • Exists until explicitly freed

๐Ÿ‘‰ Dynamic memory allocation happens in Heap Memory.


๐Ÿง  Stack vs Heap Memory

In C programming, memory is mainly divided into two parts: Stack and Heap.
Stack memory is automatically managed by the system, whereas Heap memory is manually managed by the programmer.
Understanding this difference is very important before learning dynamic memory allocation.



๐Ÿ“Œ Stack memory is used for local variables and function calls (LIFO), while Heap memory is used for dynamic memory allocation and must be manually managed using malloc(), calloc(), realloc(), and free().


๐Ÿ“Œ Why Do We Need Dynamic Memory?

Consider this:

int arr[100]; // Declares an integer array named 'arr' that can store 100 integer elements (stored in stack memory if declared inside a function)

What if the user wants to enter 1000 values?

❌ Memory insufficient
❌ Fixed size problem
❌ Memory waste if unused

With dynamic memory:

✔ Allocate only required memory
✔ Resize memory when needed
✔ Efficient memory usage


๐Ÿ”ฅ Dynamic Memory Allocation Functions

We use functions from:

#include <stdlib.h> // Includes standard library functions like malloc(), calloc(), realloc(), free(), exit(), etc.

There are 4 main functions:

  • malloc()

  • calloc()

  • realloc()

  • free()


1️⃣ malloc() – Memory Allocation

๐Ÿ”น What is malloc()?

malloc() stands for Memory Allocation.

It allocates a single block of memory of specified size at runtime.

Important Points:

  • Allocates memory in heap

  • Does NOT initialize memory (contains garbage values)

  • Returns pointer to allocated memory

  • Returns NULL if allocation fails


๐Ÿ”น Syntax

ptr = (datatype*) malloc(size_in_bytes); // Allocates 'size_in_bytes' of memory dynamically from the heap, // casts the returned void pointer to (datatype*), // and stores the starting address of the allocated memory in 'ptr'

๐Ÿ”น Fully Commented Program Using malloc()


#include <stdio.h> // Includes standard input-output library for printf() and scanf() #include <stdlib.h> // Includes standard library for malloc() and free() int main() // Main function where program execution begins { int *ptr; // Declare an integer pointer to store the address of dynamically allocated memory int n, i; // Declare 'n' for number of elements and 'i' as loop counter printf("Enter number of elements: "); // Prompt the user to enter how many elements they want scanf("%d", &n); // Read the user input and store it in variable 'n' // Allocate memory dynamically for 'n' integers in heap memory ptr = (int*) malloc(n * sizeof(int)); // Allocate memory for n integers and store starting address in ptr // Check whether memory allocation was successful if(ptr == NULL) // If malloc returns NULL, allocation failed { printf("Memory allocation failed.\n"); // Display error message return 0; // Exit the program immediately } printf("Enter %d elements:\n", n); // Ask the user to input 'n' integer values for(i = 0; i < n; i++) // Loop runs from index 0 to n-1 { scanf("%d", &ptr[i]); // Store each entered value in dynamically allocated memory } printf("You entered:\n"); // Print heading before displaying elements for(i = 0; i < n; i++) // Loop again from 0 to n-1 { printf("%d ", ptr[i]); // Print each element stored in heap memory } free(ptr); // Free the dynamically allocated memory to prevent memory leak ptr = NULL; // Set pointer to NULL to avoid dangling pointer return 0; // Indicate successful program termination }

2️⃣ calloc() – Contiguous Allocation

๐Ÿ”น What is calloc()?

calloc() stands for Contiguous Allocation.

It is used to allocate multiple blocks of memory and initializes all bytes to zero.

Important Points:

  • Takes two arguments

  • Allocates contiguous memory

  • Initializes memory to 0

  • Returns NULL if allocation fails


๐Ÿ”น Syntax

ptr = (datatype*) calloc(number_of_elements, size_of_each_element); // Allocates memory dynamically for 'number_of_elements', // each of size 'size_of_each_element' bytes in heap memory, // initializes all allocated memory to 0, // casts the returned void pointer to (datatype*), // and stores the starting address of the allocated block in 'ptr'

๐Ÿ”น Fully Commented Program Using calloc()

#include <stdio.h> // Includes standard input-output library for printf() #include <stdlib.h> // Includes standard library for calloc() and free() int main() // Main function where execution starts { int *ptr; // Declare an integer pointer to store address of dynamically allocated memory int i; // Declare loop variable // Allocate memory dynamically for 5 integers in heap memory // calloc() initializes all allocated memory to 0 ptr = (int*) calloc(5, sizeof(int)); // Check whether memory allocation was successful if(ptr == NULL) // If calloc returns NULL, allocation failed { printf("Memory allocation failed.\n"); // Display error message return 0; // Exit the program } printf("Values after calloc():\n"); // Display heading before printing values for(i = 0; i < 5; i++) // Loop runs from index 0 to 4 { printf("%d ", ptr[i]); // Print each element (all will be 0) } free(ptr); // Free dynamically allocated memory to prevent memory leak ptr = NULL; // Set pointer to NULL to avoid dangling pointer return 0; // Indicate successful program termination }

3️⃣ realloc() – Reallocate Memory

๐Ÿ”น What is realloc()?

realloc() stands for Reallocation.

It resizes previously allocated memory block.

Important Points:

  • Can increase memory size

  • Can decrease memory size

  • May move memory to new location

  • Returns NULL if reallocation fails


๐Ÿ”น Syntax

ptr = (datatype*) realloc(ptr, new_size_in_bytes); // Resizes the previously allocated memory block pointed to by 'ptr' // to 'new_size_in_bytes' bytes in heap memory, // preserves the existing data (up to the smaller of old and new size), // may move the memory block to a new location if needed, // returns the new memory address (or NULL if reallocation fails), // and stores the updated address back into 'ptr'

๐Ÿ”น Fully Commented Program Using realloc()

#include <stdio.h> // Includes standard input-output functions like printf() #include <stdlib.h> // Includes memory management functions: malloc(), realloc(), free() int main() // Program execution starts from main() { int *ptr; // Declare an integer pointer to store address of dynamic memory int i; // Declare loop variable // Allocate memory dynamically for 3 integers in heap memory ptr = (int*) malloc(3 * sizeof(int)); if(ptr == NULL) // Check if memory allocation failed { printf("Memory allocation failed.\n"); // Display error message return 0; // Exit program } // Assign values to first 3 elements for(i = 0; i < 3; i++) // Loop from index 0 to 2 { ptr[i] = i + 1; // Store values 1, 2, 3 in allocated memory } // Resize the allocated memory to hold 5 integers ptr = (int*) realloc(ptr, 5 * sizeof(int)); if(ptr == NULL) // Check if reallocation failed { printf("Reallocation failed.\n"); // Display error message return 0; // Exit program } // Assign values to the newly added memory locations for(i = 3; i < 5; i++) // Loop from index 3 to 4 { ptr[i] = i + 1; // Store values 4 and 5 } printf("Updated values:\n"); // Print heading before displaying values for(i = 0; i < 5; i++) // Loop through all 5 elements { printf("%d ", ptr[i]); // Print each element stored in heap memory } free(ptr); // Free dynamically allocated memory to prevent memory leak ptr = NULL; // Set pointer to NULL to avoid dangling pointer return 0; // Indicate successful termination }

4️⃣ free() – Deallocate Memory

๐Ÿ”น What is free()?

free() is used to deallocate memory that was allocated dynamically using malloc(), calloc(), or realloc().

If memory is not freed → ❌ Memory Leak occurs.


๐Ÿ”น Syntax

free(ptr); // Releases the dynamically allocated memory block pointed to by 'ptr' // from heap memory, preventing memory leak // After calling free(), the memory becomes available for reuse by the system

๐Ÿ”น Simple Example

#include <stdio.h> // Includes standard input-output functions like printf() #include <stdlib.h> // Includes memory management functions like malloc() and free() int main() // Program execution starts from main() { int *ptr; // Declare an integer pointer to store address of dynamic memory // Allocate memory dynamically for one integer in heap memory ptr = (int*) malloc(sizeof(int)); if(ptr == NULL) // Check if memory allocation failed { printf("Allocation failed.\n"); // Display error message return 0; // Exit program } *ptr = 100; // Store value 100 in the allocated memory (dereferencing pointer) printf("Value: %d\n", *ptr); // Print the value stored in heap memory free(ptr); // Free the dynamically allocated memory to prevent memory leak ptr = NULL; // Set pointer to NULL to avoid dangling pointer return 0; // Indicate successful program termination }

๐Ÿ“Œ *ptr = 100; means we are storing the value at the memory location pointed to by ptr. This is called dereferencing a pointer.

⚠ Common Mistakes in Dynamic Memory Allocation

❌ Not checking if malloc() returns NULL
❌ Forgetting to free memory
❌ Using memory after free()
❌ Not setting pointer to NULL after freeing
❌ Memory leak inside loops


⚠ What is Memory Leak?

When dynamically allocated memory is not freed, it remains occupied in heap memory.

Over time:

  • Program becomes slow

  • Memory gets exhausted

  • System performance decreases

Always use:

free(ptr); // Releases the dynamically allocated memory pointed to by 'ptr' from heap memory ptr = NULL; // Sets the pointer to NULL to avoid a dangling pointer (safe practice after free)

๐ŸŽฏ Viva Questions – Dynamic Memory Allocation (With Answers)


1️⃣ What is Dynamic Memory Allocation?

Dynamic Memory Allocation (DMA) is the process of allocating memory at runtime (during program execution) using functions like malloc(), calloc(), realloc(), and free().

๐Ÿ‘‰ It allows programs to request memory as needed instead of fixed memory at compile time.


2️⃣ Where is dynamic memory allocated?

Dynamic memory is allocated in the Heap area of memory.

๐Ÿ‘‰ The heap is used for runtime memory management.


3️⃣ Which header file is required?

#include <stdlib.h>

๐Ÿ‘‰ The stdlib.h header file is required for using malloc(), calloc(), realloc(), and free().


4️⃣ Difference Between Stack and Heap

Stack Heap
Memory is automatically managed Memory is manually managed
Faster access Slightly slower access
Fixed size Flexible size
Used for local variables Used for dynamic allocation
Allocated during function call Allocated using malloc(), calloc(), realloc()
Memory released automatically when function ends Memory must be released using free()
Less risk of memory leak Higher risk of memory leak
Follows LIFO (Last In First Out) Used for complex data structures (Linked List, Trees)

๐Ÿ‘‰ Stack memory is freed automatically, but heap memory must be freed manually.

5️⃣ What does malloc() return?

malloc() returns a void pointer (void)* to the allocated memory block.

๐Ÿ‘‰ It must be typecasted to the required data type.


6️⃣ What happens if malloc() fails?

If memory allocation fails, malloc() returns NULL.

๐Ÿ‘‰ Always check for NULL before using the pointer.

Example:

if(ptr == NULL) {
printf("Memory allocation failed");
}

7️⃣ Difference Between malloc() and calloc()

malloc() calloc()
Allocates a single block of memory Allocates multiple blocks of memory
Does NOT initialize memory (contains garbage values) Initializes all allocated memory to 0
Takes 1 argument (total size in bytes) Takes 2 arguments (number of elements, size of each element)
Syntax: malloc(total_size) Syntax: calloc(n, size)
Faster (no initialization overhead) Slightly slower (due to zero initialization)
Used when memory initialization is not required Used when zero-initialized memory is required
Returns a void pointer Returns a void pointer


๐Ÿ‘‰ calloc() is safer when you need zero-initialized memory.

8️⃣ Why should we use free()?

free() is used to release heap memory.

๐Ÿ‘‰ If not freed, memory remains occupied and causes memory leak.


9️⃣ What is memory leak?

A memory leak occurs when dynamically allocated memory is not freed.

๐Ÿ‘‰ It wastes memory and can crash large programs.


๐Ÿ”Ÿ What is realloc() used for?

realloc() is used to resize previously allocated memory.

๐Ÿ‘‰ It can increase or decrease memory size.


1️⃣1️⃣ Can realloc() reduce memory size?

Yes ✅
realloc() can both increase and decrease memory size.


1️⃣2️⃣ What is a dangling pointer?

A dangling pointer is a pointer that points to memory that has already been freed.

Example:

free(ptr);
// ptr still holds old address → dangling pointer

๐Ÿ‘‰ To avoid it, set pointer to NULL after free.


1️⃣3️⃣ Can free() be used on NULL pointer?

Yes ✅

Calling free(NULL) is completely safe and does nothing.


1️⃣4️⃣ Why use sizeof() with malloc()?

sizeof() ensures correct memory size allocation.

Example:

ptr = (int*)malloc(5 * sizeof(int)); // Dynamically allocates memory in heap for 5 integer elements, // calculates total required size as 5 × sizeof(int) bytes, // casts the returned void pointer to (int*), // and stores the starting address of the allocated memory in 'ptr'

๐Ÿ‘‰ This makes code portable and safe.


1️⃣5️⃣ Is heap memory automatically freed?

No ❌

Heap memory is NOT automatically freed.

๐Ÿ‘‰ Programmer must use free() manually.


๐Ÿ“ MCQs (With Answers + 1-Line Explanation)


1️⃣ Dynamic memory is allocated in:

a) Stack
b) Heap ✅
c) Code
d) Data

Answer: b
๐Ÿ‘‰ Dynamic memory is stored in the heap region.


2️⃣ malloc() initializes memory to:

a) 0
b) 1
c) Garbage value ✅
d) NULL

Answer: c
๐Ÿ‘‰ malloc() does NOT initialize memory; it contains garbage values.


3️⃣ Header file for DMA:

a) stdio.h
b) string.h
c) stdlib.h ✅
d) math.h

Answer: c
๐Ÿ‘‰ stdlib.h contains memory allocation functions.


4️⃣ calloc() initializes memory to:

a) 0 ✅
b) Garbage
c) NULL
d) Random

Answer: a
๐Ÿ‘‰ calloc() initializes allocated memory to zero.


5️⃣ realloc() is used to:

a) Free memory
b) Resize memory ✅
c) Allocate stack
d) Declare pointer

Answer: b
๐Ÿ‘‰ realloc() changes the size of previously allocated memory.


✅ Advantages of Dynamic Memory Allocation

✔ Efficient memory usage
✔ Flexible memory size
✔ Useful for data structures
✔ Runtime control


❌ Disadvantages

✖ Slower than stack
✖ Risk of memory leak
✖ Manual management required


๐Ÿš€ Final Conclusion

Dynamic Memory Allocation is one of the most powerful and essential concepts in C programming.

It allows:

Runtime memory allocation
Better control
Efficient usage
Foundation for advanced data structures

Understanding malloc(), calloc(), realloc(), and free() clearly will make your C programming level advanced and interview-ready.

Master this concept, and you unlock the door to:

๐Ÿ‘‰ Linked Lists
๐Ÿ‘‰ Trees
๐Ÿ‘‰ Graphs
๐Ÿ‘‰ Dynamic Data Structures


๐Ÿ“Œ In short, Dynamic Memory Allocation in C allows programmers to manage memory efficiently at runtime using malloc(), calloc(), realloc(), and free(). Understanding these functions is essential for mastering data structures and advanced programming concepts.


๐Ÿ“Œ Keep Learning. Keep Coding. Keep Growing.

✨ Written by Krishna Popat
๐ŸŒฑ Founder, Learning Growth Hub

Comments

Popular posts from this blog

๐ŸŒŸ The Honest Journey of a Student: Learning, Failing, and Growing

“C Programming for Beginners: Master Variables, Data Types, and Memory (Bits Explained)”