Introduction
Dynamic memory allocation allows a C program to request memory while the program is running instead of deciding the required size in advance. The main functions are malloc(), calloc(), realloc(), and free(). In this chapter, you will practice these functions with simple examples, arrays, user input, resizing memory, and proper memory release. These examples are designed to build your understanding from basic concepts to practical C programming. Dynamic Memory Allocation in C – malloc(), calloc(), realloc() AND free() Practice questions with solutions to help you understand the concepts.
Q1. Allocate Memory Using malloc()
Problem Statement
Use malloc() to dynamically allocate memory for one integer, store a value, and display it.
C Program
#include <stdio.h>
#include <stdlib.h>
int main()
{
int *ptr;
ptr = malloc(sizeof(int));
if (ptr == NULL)
{
printf("Memory allocation failed");
return 1;
}
*ptr = 100;
printf("Value = %d", *ptr);
free(ptr);
return 0;
}
Sample Output
Value = 100
Explanation
First, create an integer pointer:
int *ptr;
Then allocate enough memory for one integer:
ptr = malloc(sizeof(int));
malloc() returns the address of the allocated memory.
We check:
if (ptr == NULL)
because memory allocation can fail.
Then:
*ptr = 100;
stores 100 in the allocated memory.
Finally:
free(ptr);
releases the memory.
Concepts Covered
- Dynamic memory allocation
malloc()- Pointers
sizeof()free()NULL
Q2. Allocate Memory for Multiple Integers Using malloc()
Problem Statement
Dynamically allocate memory for five integers using malloc(), store values, and display them.
C Program
#include <stdio.h>
#include <stdlib.h>
int main()
{
int *numbers;
int i;
numbers = malloc(5 * sizeof(int));
if (numbers == NULL)
{
printf("Memory allocation failed");
return 1;
}
for (i = 0; i < 5; i++)
{
numbers[i] = (i + 1) * 10;
}
printf("Numbers:\n");
for (i = 0; i < 5; i++)
{
printf("%d ", numbers[i]);
}
free(numbers);
return 0;
}
Sample Output
Numbers:
10 20 30 40 50
Explanation
We need space for five integers:
numbers = malloc(5 * sizeof(int));
The memory can then be accessed like an array:
numbers[0]
numbers[1]
numbers[2]
numbers[3]
numbers[4]
This is an important point:
Dynamically allocated memory can be accessed using array notation.
After using the memory, release it:
free(numbers);
Concepts Covered
- Dynamic arrays
malloc()- Array indexing
sizeof()free()
Q3. Take User Input into Dynamically Allocated Memory
Problem Statement
Ask the user for the number of integers, dynamically allocate memory for them, take input, and display the numbers.
C Program
#include <stdio.h>
#include <stdlib.h>
int main()
{
int *numbers;
int n;
int i;
printf("Enter number of elements: ");
scanf("%d", &n);
if (n <= 0)
{
printf("Invalid number of elements");
return 1;
}
numbers = malloc(n * sizeof(int));
if (numbers == NULL)
{
printf("Memory allocation failed");
return 1;
}
printf("Enter %d numbers:\n", n);
for (i = 0; i < n; i++)
{
scanf("%d", &numbers[i]);
}
printf("Numbers are:\n");
for (i = 0; i < n; i++)
{
printf("%d ", numbers[i]);
}
free(numbers);
return 0;
}
Sample Output
Enter number of elements: 4
Enter 4 numbers:
10
25
40
55
Numbers are:
10 25 40 55
Explanation
Here, the number of elements is decided by the user:
scanf("%d", &n);
Then we allocate exactly the required amount:
numbers = malloc(n * sizeof(int));
If the user enters 4, the program allocates enough memory for four integers.
This is one of the main advantages of dynamic memory allocation.
Concepts Covered
- User-defined array size
malloc()- Dynamic arrays
- Input using pointers
free()
Q4. Use calloc() to Allocate an Integer Array
Problem Statement
Use calloc() to dynamically allocate memory for five integers and display their initial values.
C Program
#include <stdio.h>
#include <stdlib.h>
int main()
{
int *numbers;
int i;
numbers = calloc(5, sizeof(int));
if (numbers == NULL)
{
printf("Memory allocation failed");
return 1;
}
printf("Initial values:\n");
for (i = 0; i < 5; i++)
{
printf("%d ", numbers[i]);
}
free(numbers);
return 0;
}
Sample Output
Initial values:
0 0 0 0 0
Explanation
calloc() takes two arguments:
calloc(number_of_elements, size_of_each_element);
Here:
numbers = calloc(5, sizeof(int));
allocates space for five integers.
Unlike malloc(), calloc() initializes the allocated bytes to zero.
Therefore, the allocated integer elements have zero values on a typical system.
Concepts Covered
calloc()- Dynamic arrays
- Zero initialization
free()
Q5. Understand the Difference Between malloc() and calloc()
Problem Statement
Create one integer array using malloc() and another using calloc(). Understand the difference between their initialization behavior.
C Program
#include <stdio.h>
#include <stdlib.h>
int main()
{
int *a;
int *b;
int i;
a = malloc(5 * sizeof(int));
b = calloc(5, sizeof(int));
if (a == NULL || b == NULL)
{
printf("Memory allocation failed");
free(a);
free(b);
return 1;
}
for (i = 0; i < 5; i++)
{
a[i] = i + 1;
}
printf("malloc() array:\n");
for (i = 0; i < 5; i++)
{
printf("%d ", a[i]);
}
printf("\ncalloc() array:\n");
for (i = 0; i < 5; i++)
{
printf("%d ", b[i]);
}
free(a);
free(b);
return 0;
}
Sample Output
malloc() array:
1 2 3 4 5
calloc() array:
0 0 0 0 0
Explanation
malloc():
malloc(5 * sizeof(int));
allocates memory but does not initialize the allocated bytes.
calloc():
calloc(5, sizeof(int));
allocates memory and initializes the allocated bytes to zero.
A simple comparison:
| Function | Arguments | Initial state |
|---|---|---|
malloc() | Total number of bytes | Uninitialized |
calloc() | Number of elements + size | All allocated bytes initialized to zero |
Concepts Covered
malloc()calloc()- Memory initialization
- Dynamic arrays
free()
Q6. Resize Memory Using realloc()
Problem Statement
Initially allocate memory for three integers. Then increase the memory to hold five integers using realloc().
C Program
#include <stdio.h>
#include <stdlib.h>
int main()
{
int *numbers;
int *temp;
int i;
numbers = malloc(3 * sizeof(int));
if (numbers == NULL)
{
printf("Memory allocation failed");
return 1;
}
numbers[0] = 10;
numbers[1] = 20;
numbers[2] = 30;
printf("Before resizing:\n");
for (i = 0; i < 3; i++)
{
printf("%d ", numbers[i]);
}
temp = realloc(numbers, 5 * sizeof(int));
if (temp == NULL)
{
printf("\nMemory resizing failed");
free(numbers);
return 1;
}
numbers = temp;
numbers[3] = 40;
numbers[4] = 50;
printf("\nAfter resizing:\n");
for (i = 0; i < 5; i++)
{
printf("%d ", numbers[i]);
}
free(numbers);
return 0;
}
Sample Output
Before resizing:
10 20 30
After resizing:
10 20 30 40 50
Explanation
First, memory is allocated for three integers:
numbers = malloc(3 * sizeof(int));
Then we resize it:
temp = realloc(numbers, 5 * sizeof(int));
Using a temporary pointer is safer than directly writing:
numbers = realloc(numbers, 5 * sizeof(int));
because if realloc() fails, assigning NULL directly to numbers would lose the original pointer and potentially cause a memory leak.
After successful reallocation:
numbers = temp;
The block can now hold five integers.
Concepts Covered
realloc()- Resizing memory
- Temporary pointer
- Dynamic arrays
- Memory leak prevention
Q7. Reduce Dynamically Allocated Memory
Problem Statement
Allocate memory for five integers and then reduce the allocated memory to three integers using realloc().
C Program
#include <stdio.h>
#include <stdlib.h>
int main()
{
int *numbers;
int *temp;
int i;
numbers = malloc(5 * sizeof(int));
if (numbers == NULL)
{
printf("Memory allocation failed");
return 1;
}
for (i = 0; i < 5; i++)
{
numbers[i] = (i + 1) * 10;
}
printf("Before resizing:\n");
for (i = 0; i < 5; i++)
{
printf("%d ", numbers[i]);
}
temp = realloc(numbers, 3 * sizeof(int));
if (temp == NULL)
{
printf("\nMemory resizing failed");
free(numbers);
return 1;
}
numbers = temp;
printf("\nAfter resizing:\n");
for (i = 0; i < 3; i++)
{
printf("%d ", numbers[i]);
}
free(numbers);
return 0;
}
Sample Output
Before resizing:
10 20 30 40 50
After resizing:
10 20 30
Explanation
Initially, five integers are allocated:
numbers = malloc(5 * sizeof(int));
Then:
temp = realloc(numbers, 3 * sizeof(int));
changes the requested size to three integers.
After shrinking the allocation, only the first three elements are within the resized allocation.
Therefore, we access only:
numbers[0]
numbers[1]
numbers[2]
We must not access the old fourth and fifth elements after shrinking.
Concepts Covered
realloc()- Shrinking memory
- Dynamic arrays
- Valid memory boundaries
Q8. Dynamically Allocate Memory for a Structure
Problem Statement
Create a Student structure and dynamically allocate memory for one student using malloc().
C Program
#include <stdio.h>
#include <stdlib.h>
struct Student
{
int roll;
char name[50];
float marks;
};
int main()
{
struct Student *student;
student = malloc(sizeof(struct Student));
if (student == NULL)
{
printf("Memory allocation failed");
return 1;
}
student->roll = 101;
snprintf(student->name, sizeof(student->name), "%s", "Rahul");
student->marks = 88.5;
printf("Roll = %d\n", student->roll);
printf("Name = %s\n", student->name);
printf("Marks = %.2f\n", student->marks);
free(student);
return 0;
}
Sample Output
Roll = 101
Name = Rahul
Marks = 88.50
Explanation
Instead of creating a structure directly:
struct Student student;
we dynamically allocate it:
student = malloc(sizeof(struct Student));
Because student is a pointer to a structure, we use the -> operator:
student->roll
student->name
student->marks
After using the structure:
free(student);
releases its dynamically allocated memory.
Concepts Covered
malloc()- Structures
- Structure pointers
->operatorfree()
Q9. Create a Dynamically Sized Array and Calculate the Average
Problem Statement
Ask the user for the number of marks, dynamically allocate memory, accept the marks, and calculate their average.
C Program
#include <stdio.h>
#include <stdlib.h>
int main()
{
float *marks;
int n;
int i;
float sum = 0.0f;
float average;
printf("Enter number of students: ");
scanf("%d", &n);
if (n <= 0)
{
printf("Invalid number of students");
return 1;
}
marks = malloc(n * sizeof(float));
if (marks == NULL)
{
printf("Memory allocation failed");
return 1;
}
printf("Enter marks:\n");
for (i = 0; i < n; i++)
{
scanf("%f", &marks[i]);
sum += marks[i];
}
average = sum / n;
printf("Average = %.2f", average);
free(marks);
return 0;
}
Sample Output
Enter number of students: 4
Enter marks:
80
75
90
85
Average = 82.50
Explanation
The user decides how many marks are required:
scanf("%d", &n);
Then memory is allocated:
marks = malloc(n * sizeof(float));
Each mark is stored dynamically:
scanf("%f", &marks[i]);
We add each mark to:
sum += marks[i];
Finally:
average = sum / n;
The dynamically allocated memory is released using:
free(marks);
Concepts Covered
- Dynamic array
malloc()floatarrays- User input
- Average calculation
free()
Q10. Build a Dynamic Array That Grows with realloc()
Problem Statement
Start with memory for two integers. Ask the user for five numbers and increase the memory as required using realloc().
C Program
#include <stdio.h>
#include <stdlib.h>
int main()
{
int *numbers;
int *temp;
int size = 2;
int count = 0;
int value;
numbers = malloc(size * sizeof(int));
if (numbers == NULL)
{
printf("Memory allocation failed");
return 1;
}
while (count < 5)
{
printf("Enter number %d: ", count + 1);
scanf("%d", &value);
if (count == size)
{
size = size * 2;
temp = realloc(numbers, size * sizeof(int));
if (temp == NULL)
{
printf("Memory resizing failed");
free(numbers);
return 1;
}
numbers = temp;
}
numbers[count] = value;
count++;
}
printf("\nNumbers entered:\n");
for (int i = 0; i < count; i++)
{
printf("%d ", numbers[i]);
}
free(numbers);
return 0;
}
Sample Output
Enter number 1: 10
Enter number 2: 20
Enter number 3: 30
Enter number 4: 40
Enter number 5: 50
Numbers entered:
10 20 30 40 50
Explanation
Initially, memory is allocated for two integers:
size = 2;
numbers = malloc(size * sizeof(int));
When the array becomes full:
if (count == size)
we increase the capacity:
size = size * 2;
Then we resize the memory:
temp = realloc(numbers, size * sizeof(int));
This technique is useful for building dynamically growing arrays.
The important idea is:
Initial capacity
↓
2
↓
Array becomes full
↓
realloc()
↓
4
↓
Array becomes full
↓
realloc()
↓
8
In this example, only five values are needed, so the capacity grows from 2 to 4 and then to 8.
Concepts Covered
malloc()realloc()- Dynamic array growth
- Pointers
- Temporary pointer
free()
Key Takeaways
- Dynamic memory allocation allows a C program to request memory during runtime.
malloc()allocates a specified number of bytes.- Memory returned by
malloc()is not initialized. calloc()allocates memory for multiple elements and initializes the allocated bytes to zero.realloc()changes the size of an existing dynamic memory allocation.free()releases dynamically allocated memory.- Always include
<stdlib.h>when using these functions. - Check whether
malloc(),calloc(), orrealloc()returnedNULL. - Use a temporary pointer when handling
realloc()safely. - Never access dynamically allocated memory after it has been freed.
- Avoid accessing memory outside the allocated range.
- Forgetting to release dynamically allocated memory can cause memory leaks.
- Dynamic arrays are useful when the required size is not known until runtime.
FAQs
1. What is dynamic memory allocation in C?
Dynamic memory allocation is the process of requesting and managing memory while a program is running. It is useful when the required amount of memory is not known in advance.
2. What is malloc() in C?
malloc() allocates a specified number of bytes of memory and returns a pointer to the allocated block. The allocated bytes are not initialized.
Example:
int *ptr = malloc(5 * sizeof(int));
3. What is the difference between malloc() and calloc()?
malloc() takes the total number of bytes and does not initialize the allocated memory. calloc() takes the number of elements and the size of each element and initializes the allocated bytes to zero.
4. What is realloc() used for?
realloc() is used to change the size of an existing dynamically allocated memory block.
For example:
ptr = realloc(ptr, 10 * sizeof(int));
It can be used to expand or reduce an allocation.
5. Why is free() important in C?
free() releases dynamically allocated memory when it is no longer required. Not releasing memory can lead to memory leaks.
6. What happens if malloc() fails?
If malloc() cannot allocate the requested memory, it returns NULL. The program should check for this before using the returned pointer.
if (ptr == NULL)
{
printf("Memory allocation failed");
}
7. Can dynamically allocated memory be used like an array?
Yes. For example:
int *numbers = malloc(5 * sizeof(int));
allows you to use:
numbers[0]
numbers[1]
numbers[2]
numbers[3]
numbers[4]
as long as the allocation is valid and those indexes are within its bounds.
Written by Shubhranshu Shekhar, who has trained 20000+ students in coding.
