Dynamic Memory Allocation in C – malloc(), calloc(), realloc() AND free() Practice Questions with Solutions

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:

FunctionArgumentsInitial state
malloc()Total number of bytesUninitialized
calloc()Number of elements + sizeAll 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
  • -> operator
  • free()

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()
  • float arrays
  • 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(), or realloc() returned NULL.
  • 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.

Scroll to Top