For working professionals
For fresh graduates
More
5. Array in C
13. Boolean in C
18. Operators in C
33. Comments in C
38. Constants in C
41. Data Types in C
49. Double In C
58. For Loop in C
60. Functions in C
70. Identifiers in C
81. Linked list in C
83. Macros in C
86. Nested Loop in C
97. Pseudo-Code In C
100. Recursion in C
103. Square Root in C
104. Stack in C
106. Static function in C
107. Stdio.h in C
108. Storage Classes in C
109. strcat() in C
110. Strcmp in C
111. Strcpy in C
114. String Length in C
115. String Pointer in C
116. strlen() in C
117. Structures in C
119. Switch Case in C
120. C Ternary Operator
121. Tokens in C
125. Type Casting in C
126. Types of Error in C
127. Unary Operator in C
128. Use of C Language
Dynamic memory allocation in C lets you allocate memory at runtime, unlike static allocation, where memory is fixed at compile-time. This flexibility is crucial for handling variable-sized data structures like arrays and linked lists, allowing programs to use memory efficiently.
For example, instead of defining an array with a fixed size:
int arr[100]; // Fixed size, may waste memory
You can allocate memory dynamically based on user input:
int *arr = (int*)malloc(n * sizeof(int)); // Allocates memory for 'n' elements
This ensures no memory is wasted and you can release memory when no longer needed using free().
In this tutorial, you’ll learn key dynamic memory functions (malloc, calloc, realloc, free), their benefits, and how to prevent memory leaks with real-world examples.
Improve your C programming skills with our Software Development courses — take the next step in your learning journey!
In C programming, arrays have a fixed size, meaning their length cannot be changed once defined. However, there are scenarios where resizing an array becomes necessary:
1. Reducing the Array Size → If an array is declared with 9 elements, but only 5 elements are needed, the remaining 4 indices waste memory. To optimize memory usage, the array size should be reduced.
2. Expanding the Array Size → If an array of 9 elements is fully occupied, but 3 more elements need to be added, the array size must be increased to 12.
Since C does not support automatic array resizing, dynamic memory allocation is used to increase or decrease the size of an array at runtime, ensuring efficient memory management in C.
Also Read: Command Line Arguments in C Explained
Dynamic memory allocation allows resizing arrays dynamically for efficient memory usage. To fully understand this, let’s first explore how memory management works in C.
Before understanding dynamic memory allocation, it's important to know how memory is managed in C.
C divides memory into different segments—stack, heap, data, and code—each serving a specific purpose.
1. Text Segment → Stores the program’s executable code.
2. Static/Global Data Segment → Holds global and static variables that are allocated before the program starts and remain throughout execution.
3. Stack Segment → Used for function calls, local variables, and parameters. Memory is automatically allocated and deallocated as functions execute.
4. Heap Segment → Used for dynamic memory allocation in C. Memory is allocated at runtime and can be freed when no longer needed.
The heap segment is managed using dynamic memory allocation functions like:
Understanding these segments helps optimize memory usage and prevent memory leaks in C programming.
Also Read: Difference Between C and Java: Which One Should You Learn?
Now, let’s explore each of the specialized dynamic memory allocation functions in more detail.
Dynamic memory allocation in C allows allocating and deallocating memory at runtime, making programs more flexible and memory-efficient. The functions responsible for this reside in <stdlib.h> and work in the heap segment.
Let's explore them with examples.
The malloc() (memory allocation) function allocates a block of memory in the heap and returns a pointer to it. However, it does not initialize the memory, meaning the allocated space may contain garbage values (previous data left in memory).
When to Use malloc()?
Syntax:
void* malloc(size_t size);
Example Code:
#include <stdio.h>
#include <stdlib.h>
int main() {
int *ptr;
int n = 5;
// Allocate memory for 5 integers
ptr = (int*)malloc(n * sizeof(int));
if (ptr == NULL) {
printf("Memory allocation failed\n");
return 1;
}
// Assign and print values
for (int i = 0; i < n; i++) {
ptr[i] = i + 1;
printf("%d ", ptr[i]);
}
// Free allocated memory
free(ptr);
return 0;
}
Output:
1 2 3 4 5
Explanation:
While malloc() is widely used for dynamic memory allocation, it is not inherently thread-safe, which can cause race conditions and performance bottlenecks in multi-threaded applications.
To improve memory allocation in concurrent environments, optimizations of malloc() like tcmalloc (Thread-Caching Malloc), jemalloc (used in MySQL & Redis), and mimalloc (lightweight & high-performance malloc alternative) have been developed.
These multi-threaded memory allocators improve efficiency by reducing thread contention, fragmentation, and memory allocation overhead. This makes them ideal for high-performance computing, AI models, and database systems.
The calloc() (contiguous allocation) function allocates memory and initializes it to zero. This ensures that the allocated memory does not contain garbage values, making it safer than malloc().
When to Use calloc()?
Syntax:
void* calloc(size_t num, size_t size);
Example Code:
#include <stdio.h>
#include <stdlib.h>
int main() {
int *ptr;
int n = 5;
// Allocate memory for 5 integers and initialize to 0
ptr = (int*)calloc(n, sizeof(int));
if (ptr == NULL) {
printf("Memory allocation failed\n");
return 1;
}
// Print values (initialized to 0)
for (int i = 0; i < n; i++) {
printf("%d ", ptr[i]);
}
free(ptr); // Free memory
return 0;
}
Output:
0 0 0 0 0
Explanation:
The realloc() (reallocate memory) function resizes an existing memory block without losing its contents. It can be used to increase or decrease the allocated memory dynamically.
If a larger block is needed and space is unavailable at the current location, realloc() moves the memory block to a new location.
When to Use realloc()?
Syntax:
void* realloc(void* ptr, size_t new_size);
Example:
#include <stdio.h>
#include <stdlib.h>
int main() {
int *ptr;
int n = 5;
// Allocate memory for 5 integers
ptr = (int*)malloc(n * sizeof(int));
if (ptr == NULL) {
printf("Memory allocation failed\n");
return 1;
}
// Assign values
for (int i = 0; i < n; i++) {
ptr[i] = i + 1;
}
// Increase size to 10 integers
ptr = (int*)realloc(ptr, 10 * sizeof(int));
if (ptr == NULL) {
printf("Memory reallocation failed\n");
return 1;
}
// Assign new values
for (int i = n; i < 10; i++) {
ptr[i] = i + 1;
}
// Print values
for (int i = 0; i < 10; i++) {
printf("%d ", ptr[i]);
}
free(ptr); // Free memory
return 0;
}
Output:
1 2 3 4 5 6 7 8 9 10
Explanation:
The free() function releases previously allocated memory back to the system, preventing memory leaks.
When to Use free()?
Syntax:
void free(void* ptr);
Example:
#include <stdio.h>
#include <stdlib.h>
int main() {
int *ptr;
int n = 5;
// Allocate memory
ptr = (int*)malloc(n * sizeof(int));
if (ptr == NULL) {
printf("Memory allocation failed\n");
return 1;
}
// Assign values
for (int i = 0; i < n; i++) {
ptr[i] = i + 1;
}
// Print values
for (int i = 0; i < n; i++) {
printf("%d ", ptr[i]);
}
// Free memory
free(ptr);
return 0;
}
Output:
1 2 3 4 5
Explanation:
Here are the key differences between the different functions:
Function | Purpose | Initializes Memory? | Can Resize? | Must Be Freed? |
malloc() | Allocates memory | No | No | Yes |
calloc() | Allocates and initializes to 0 | Yes | No | Yes |
realloc() | Resizes allocated memory | No (original values remain) | Yes | Yes |
free() | Deallocates memory | No | No | Yes |
Mastering these functions is essential for handling dynamic data structures like linked lists, stacks, and queues efficiently!
Also Read: Top 25+ C Programming Projects for Beginners and Professionals
While functions like malloc(), calloc(), realloc(), and free() help manage memory, improper usage can cause memory leaks, a major issue in dynamic allocation.
A memory leak occurs when dynamically allocated memory is not properly deallocated, leading to wasted memory that cannot be reused. Over time, this can cause excessive memory usage, performance degradation, and even program crashes.
Here are a few common causes of memory leaks:
1. Forgetting to Deallocate Memory (free())
When dynamically allocated memory is not freed, it remains in use, even after the program ends.
Example (Memory Leak Due to Missing free()):
#include <stdio.h>
#include <stdlib.h>
int main() {
int *ptr;
// Allocate memory for 5 integers
ptr = (int*)malloc(5 * sizeof(int));
if (ptr == NULL) {
printf("Memory allocation failed\n");
return 1;
}
// Assign values
for (int i = 0; i < 5; i++) {
ptr[i] = i + 1;
}
printf("Memory allocated but not freed.\n");
// Forgot to use free(ptr); - Memory Leak occurs
return 0;
}
Problem: The program allocates memory but does not free it, causing a memory leak.
Solution: Always deallocate memory once you're done using it with free(ptr);
free(ptr); // Fix: Release allocated memory
2. Losing the Reference to Allocated Memory
If a pointer holding a dynamically allocated memory block is overwritten without freeing the original memory, the original memory becomes inaccessible (lost), leading to a memory leak.
Example (Pointer Overwrite Without Freeing Previous Memory):
#include <stdio.h>
#include <stdlib.h>
int main() {
int *ptr;
// Allocate memory
ptr = (int*)malloc(5 * sizeof(int));
if (ptr == NULL) return 1;
// Overwriting the pointer before freeing old memory
ptr = (int*)malloc(10 * sizeof(int)); // Previous memory is lost!
printf("Pointer reassigned without freeing previous allocation.\n");
free(ptr); // Frees only the new allocation, not the lost memory
return 0;
}
Problem: The first allocated memory (malloc(5 * sizeof(int))) is lost forever when ptr is reassigned.
Solution: Always free the old memory before assigning a new memory block.
free(ptr);
ptr = (int*)malloc(10 * sizeof(int)); // Now memory is managed correctly
3. Premature Program Termination
If a program exits before freeing allocated memory, memory remains occupied until the system reclaims it.
Example (Exiting Program Before Freeing Memory):
#include <stdio.h>
#include <stdlib.h>
int main() {
int *ptr = (int*)malloc(5 * sizeof(int));
if (ptr == NULL) return 1;
printf("Exiting before freeing memory...\n");
exit(0); // Program terminates before freeing memory (memory leak!)
}
Problem: exit(0); terminates the program before calling free(ptr);, causing a memory leak.
Solution: Always free dynamically allocated memory before exiting the program.
free(ptr);
exit(0);
Here are some best practices you can follow to prevent memory leaks:
1. Always Deallocate Memory (free()) After Use
Every malloc(), calloc(), or realloc() must be paired with a free().
int *ptr = (int*)malloc(10 * sizeof(int));
free(ptr); // Properly releasing memory
2. Avoid Losing References to Allocated Memory
int *ptr = (int*)malloc(5 * sizeof(int));
free(ptr); // Free previous memory before reassigning
ptr = (int*)malloc(10 * sizeof(int));
3. Use NULL After Freeing Memory to Avoid Dangling Pointers
After freeing memory, set the pointer to NULL to avoid accessing invalid memory.
free(ptr);
ptr = NULL;
4. Use Memory Leak Detection Tools
Valgrind (Linux) → Detects memory leaks in C programs.
valgrind --leak-check=full ./a.out
AddressSanitizer (GCC/Clang) → Helps find memory issues.
gcc -fsanitize=address program.c -o program && ./program
Here’s a memory leak detection example using Valgrind:
#include <stdlib.h>
int main() {
int *ptr = (int*)malloc(5 * sizeof(int));
// Forgot to free memory
return 0;
}
Detecting Memory Leak with Valgrind:
valgrind --leak-check=full ./a.out
Output:
==1234== ERROR SUMMARY: 1 memory leak detected
==1234== 20 bytes in 1 blocks lost
Fix:
free(ptr);
Mastering memory management in C ensures better resource utilization, especially when working with large datasets and long-running applications.
Also Read: Command Line Arguments in C Explained
Memory leaks occur when allocated memory isn’t freed, leading to performance issues. To prevent this, let’s explore the correct methods for deallocating memory.
Dynamic memory allocation in C provides flexibility, but failing to properly deallocate memory can lead to memory leaks. The free() function is the standard way to release dynamically allocated memory in C, but in some cases, memory is automatically reclaimed by the operating system upon program termination.
1. How to Deallocate Memory Using free()
The free() function releases dynamically allocated memory back to the system, making it available for future use. Once freed, accessing the memory becomes undefined behavior and should be avoided.
Steps to Deallocate Memory Using free():
Example: Properly Freeing Memory
#include <stdio.h>
#include <stdlib.h>
int main() {
int *ptr; // Pointer for dynamic memory allocation
// Allocate memory for an integer
ptr = (int*)malloc(sizeof(int));
if (ptr == NULL) {
printf("Memory allocation failed\n");
return 1;
}
*ptr = 10; // Assign a value
printf("Value: %d\n", *ptr);
// Deallocate memory
free(ptr);
ptr = NULL; // Avoids dangling pointer
return 0;
}
Output:
Value: 10
Explanation:
Best Practice: Always pair malloc() / calloc() / realloc() with free() to avoid memory leaks.
2. Deallocating Memory Without Using free()
In some cases, manual deallocation isn’t needed because the operating system automatically reclaims memory when the program exits. However, this is not recommended for long-running programs, as failing to free memory leads to memory leaks.
When is free() Unnecessary?
Example: Memory Automatically Reclaimed by OS
#include <stdio.h>
#include <stdlib.h>
void allocateMemory() {
int *ptr = (int*)malloc(sizeof(int)); // Allocating memory
if (ptr == NULL) return;
*ptr = 20;
printf("Value inside function: %d\n", *ptr);
// No free() call, memory will be reclaimed when program exits
}
int main() {
allocateMemory(); // Memory is allocated but not freed explicitly
printf("Program ends, OS reclaims memory.\n");
return 0;
}
Output:
Value inside function: 20Program ends, OS reclaims memory.
Explanation:
Drawback: Relying on the OS for cleanup is unsafe for programs that run indefinitely, such as servers or background processes.
Here are the key differences between free() and OS memory reclamation:
Method | When Memory is Reclaimed | Best For | Risk |
free() | Immediately when called | Long-running programs | Prevents memory leaks |
OS Reclamation | At program termination | Short-lived programs | Risk of memory leaks |
Best Practice: Always use free() unless you are sure the OS will handle cleanup safely.
Also Read: What Are Storage Classes in C?
The free() function is essential for releasing allocated memory, but in some cases, memory is managed automatically. Now, let’s look at real-world applications of dynamic memory allocation.
Dynamic memory allocation in C is widely used in real-world applications where flexible and efficient memory management is crucial.
It plays a vital role in traditional computing domains such as operating systems and networking, as well as in emerging technologies like AI, quantum computing, and IoT.
Additionally, memory pooling has become a key optimization technique in performance-critical applications such as gaming, embedded systems, and high-frequency trading.
Some key applications include:
1. Operating Systems
2. High-Performance Computing (HPC) & AI
3. Quantum Computing Simulations
4.Embedded Systems, Edge Computing & IoT Devices
5. Game Development & Simulations
6. Networking & Communication Systems
7. Image & Video Processing
8. Cybersecurity & Encryption
9. Cloud Computing & Virtualization
10. Scientific Computing & Machine Learning
Dynamic memory allocation makes software scalable, efficient, and adaptable to real-world challenges!
Also Read: Data Types in C and C++ Explained for Beginners
While dynamic memory allocation is beneficial, it also has drawbacks, which you’ll have to keep in mind.
Dynamic memory allocation enables flexible memory management in C, optimizing data structures, real-time applications, and scalability. Although it improves efficiency and adaptability, it poses risks like memory leaks, fragmentation, and runtime overhead. Proper management ensures efficient and error-free memory usage.
Here’s a table with its advantages and disadvantages:
Category | Benefits | Drawbacks |
Memory Utilization | Allocates memory only when needed, preventing wastage. | Risk of memory leaks if free() is not used properly. |
Flexibility | Allows dynamic resizing using realloc(), useful for growing datasets. | Slower execution compared to static allocation due to runtime processing. |
Data Structure Support | Enables efficient implementation of linked lists, trees, graphs, stacks, and queues. | Increases code complexity due to manual memory management in C. |
Performance Optimization | Prevents unnecessary memory occupation, improving scalability and speed. | Can lead to memory fragmentation, making large allocations inefficient. |
Real-Time Data Handling | Used in networking, game development, and AI models for real-time memory allocation. | Heap memory is limited, excessive allocations may cause out-of-memory errors. |
Also Read: What is Array in C? With Examples
Dynamic memory allocation enhances flexibility and efficiency, but risks fragmentation and leaks. To reinforce your understanding, take this quick quiz.
These MCQs will test your understanding of dynamic memory allocation in C, covering memory management functions, real-life applications, benefits, drawbacks, and best practices.
1. Which memory segment is used for dynamic memory allocation in C?
a) Stack
b) Heap
c) Data Segment
d) Code Segment
2. Which function is used to allocate memory but does not initialize it?
a) calloc()
b) malloc()
c) realloc()
d) free()
3. What happens if you try to access memory after calling free(ptr);?
a) The program will always crash
b) The pointer will automatically be reset to NULL
c) It leads to undefined behavior
d) The program will continue running without issues
4. Which function is used to resize previously allocated memory?
a) malloc()
b) calloc()
c) realloc()
d) free()
5. What is the best way to prevent memory leaks in dynamic memory allocation?
a) Always use malloc() instead of calloc()
b) Use realloc() before calling free()
c) Free allocated memory using free() when it is no longer needed
d) Avoid using dynamic memory allocation in programs
6. What is the major drawback of dynamic memory allocation?
a) It cannot allocate memory at runtime
b) It is slower than static memory allocation due to runtime overhead
c) It is required for small programs
d) It does not support data structures
7. Which of the following is NOT a real-life application of dynamic memory allocation?
a) Operating system process management
b) Video game object creation
c) Static array allocation
d) Dynamic data handling in networking
8. What happens if malloc() fails to allocate memory?
a) The program crashes
b) It returns NULL
c) It assigns a garbage address
d) It automatically tries to reallocate memory
9. Why is fragmentation a common issue in dynamic memory allocation?
a) Due to frequent allocation and deallocation, memory blocks become scattered
b) Because malloc() does not allocate memory
c) It only occurs in stack memory
d) Memory cannot be deallocated once allocated
10. How does calloc() differ from malloc()?
a) calloc() allocates memory faster than malloc()
b) calloc() initializes the allocated memory to zero, whereas malloc() does not
c) calloc() requires manual deallocation, but malloc() does not
d) There is no difference between them
Understanding dynamic memory allocation is just the beginning—keep building your C programming skills with expert-led courses and hands-on learning.
Also Read: Memory Allocation in Java: Everything You Need To Know in 2025
If you’re looking to expand your skills further, see how upGrad can help you master C programming.
upGrad’s courses provide in-depth training in C programming, covering fundamental concepts like loops, recursion, functions, and pointers. You’ll gain hands-on experience in writing efficient C programs, including factorial calculations, data structures, and algorithm optimization.
C remains highly relevant in modern applications, from AI-driven frameworks and HPC to IoT and quantum computing. By learning C programming, you’ll build a strong foundation for software development, competitive programming, and system-level programming.
Check out some of these upGrad courses to take your programming skills to the next level!
You can also get personalized career counseling with upGrad to guide your career path, or visit your nearest upGrad center and start hands-on training today!
Similar Reads:
Explore C Tutorials: From Beginner Concepts to Advanced Techniques
Array in C: Introduction, Declaration, Initialisation and More
Exploring Array of Pointers in C: A Beginner's Guide
What is C Function Call Stack: A Complete Tutorial
Binary Search in C
Constant Pointer in C: The Fundamentals and Best Practices
Find Out About Data Structures in C and How to Use Them?
A: Nothing. The free() function safely ignores NULL pointers, preventing crashes.
A: Check if malloc() returns NULL. A NULL return means memory allocation failed due to insufficient system memory.
A: A dangling pointer points to memory that has been freed. To avoid it, set the pointer to NULL after freeing it.
A: realloc() fails if no contiguous memory is available. Always store the result in a temporary pointer before assigning it to avoid losing memory.
A: Frequent allocations cause fragmentation, slow down the program, and may exhaust memory, leading to crashes.
A: Stack overflow occurs due to excessive recursion or large local variables, while heap exhaustion happens when excessive memory is allocated dynamically without proper deallocation.
A: Some memory allocators keep freed memory for reuse instead of returning it to the OS immediately, especially in long-running programs.
A: No. Freeing non-heap memory (e.g., local variables) causes undefined behavior and may crash the program.
A: Frequent allocation and deallocation create scattered free blocks, reducing available contiguous memory and increasing allocation time.
A: It causes a memory leak, as new memory is allocated repeatedly without releasing the old one, leading to high memory usage.
A: Use tools like Valgrind (Linux) or AddressSanitizer (GCC/Clang) to detect memory leaks and track unfreed memory.
Take a Free C Programming Quiz
Answer quick questions and assess your C programming knowledge
Author
Start Learning For Free
Explore Our Free Software Tutorials and Elevate your Career.
Talk to our experts. We are available 7 days a week, 9 AM to 12 AM (midnight)
Indian Nationals
1800 210 2020
Foreign Nationals
+918045604032
1.The above statistics depend on various factors and individual results may vary. Past performance is no guarantee of future results.
2.The student assumes full responsibility for all expenses associated with visas, travel, & related costs. upGrad does not provide any a.