Back to C Programming
2026-07-155 min read

Dynamic allocation

Learn Dynamic allocation step by step with clear examples and exercises.

Why This Matters

Dynamic allocation is a crucial concept in C programming that allows you to allocate memory at runtime, enabling the creation of complex data structures like linked lists and dynamic arrays. This guide will provide a detailed walkthrough of dynamic allocation, common mistakes, practice questions, and frequently asked questions.

Why Dynamic Allocation Matters

Dynamic allocation is essential for creating flexible programs that can handle varying amounts of data without prior knowledge of the size. It's particularly useful in scenarios where the amount of data to be processed is not known at compile time or may change during program execution. For example, when reading input from a file or user interaction, dynamic allocation ensures that your program can efficiently manage memory resources.

Prerequisites

To understand dynamic allocation, you should be familiar with:

  1. C programming basics, including variables, data types, and control structures
  2. Pointers in C, including pointer variables and pointer arithmetic
  3. Memory management functions like malloc() and free()

Core Concept

Dynamic allocation in C is primarily achieved using the malloc() function, which reserves a specified amount of memory space for your program. To dynamically allocate memory, you need to have a pointer ready to store the location of the newly allocated memory.

#include <stdio.h>
#include <stdlib.h>

typedef struct {
char *name;
int age;
} person;

int main() {
// Allocate memory for a new person
person *myperson = (person *) malloc(sizeof(person));

// Access the person's members
myperson->name = "John";
myperson->age = 27;

printf("Name: %s\nAge: %d\n", myperson->name, myperson->age);

// Release the allocated memory when done
free(myperson);

return 0;
}

In this example, we first define a person structure with two members: name and age. To dynamically allocate memory for a new person, we use the malloc() function with the size of the person struct. We then cast the returned pointer to the appropriate type using (person *). Afterward, we can access the members of the dynamically allocated struct using the arrow operator (->) and release the memory once we're done using the free() function.

Worked Example

Let's create a simple program that dynamically allocates an array of integers and performs some operations on it:

#include <stdio.h>
#include <stdlib.h>

int main() {
int size, sum = 0;
int *arr;

printf("Enter the number of elements: ");
scanf("%d", &size);

// Allocate memory for an array of integers
arr = (int *) malloc(size * sizeof(int));

if (arr == NULL) {
printf("Memory allocation failed!\n");
return 1;
}

printf("Enter %d elements:\n", size);
for (int i = 0; i < size; ++i) {
scanf("%d", &arr[i]);
sum += arr[i];
}

printf("The sum of the entered elements is: %d\n", sum);

free(arr);

return 0;
}

In this example, we first ask the user to input the number of elements in the array. We then dynamically allocate memory for an array of integers using malloc(). After checking if memory allocation was successful, we prompt the user to enter the elements and calculate their sum. Once we're done, we release the allocated memory using free().

Common Mistakes

  1. Forgetting to include the necessary header files (stdio.h and stdlib.h): Always make sure you have both header files included at the beginning of your program.
  2. Not checking if malloc() returns NULL: If memory allocation fails, it's essential to handle the error gracefully by printing an error message and exiting the program.
  3. Leaking memory: Always remember to free dynamically allocated memory once you're done using it to avoid memory leaks.
  4. Accessing uninitialized memory: Be careful when accessing elements of dynamically allocated arrays before they have been initialized, as this can lead to undefined behavior.
  5. Not handling dynamic array resizing correctly: If you're working with dynamic arrays and need to resize them, make sure to handle the edge cases properly and avoid potential bugs.

Practice Questions

  1. Write a program that dynamically allocates a struct representing a student with fields for name, roll number, and marks in three subjects. Prompt the user to enter data for multiple students, store it in an array of structures, and calculate the total marks obtained by each student.
  2. Create a dynamic array of strings that stores the names of cities. Allow the user to add, remove, and search for city names in the array.
  3. Write a program that reads a file containing integers separated by spaces and dynamically allocates an array to store them. Calculate the minimum, maximum, and average values in the array.

FAQ

  1. Why do we need dynamic allocation when we can use static arrays?

Dynamic allocation allows for greater flexibility as it enables handling varying amounts of data without prior knowledge of the size. Static arrays have a fixed size at compile time, making them less suitable for applications that require dynamic memory management.

  1. What happens if we don't free dynamically allocated memory?

If you don't free dynamically allocated memory, it will leak and consume valuable system resources, potentially causing your program to run slowly or even crash.

  1. Can I use calloc() instead of malloc() for initializing dynamically allocated memory to zero?

Yes, calloc() is used when you want to initialize dynamically allocated memory to zero. It calculates the number of elements and multiplies it by the size of each element before returning a pointer to the allocated memory.

  1. What's the difference between malloc(), calloc(), and realloc()?

malloc() reserves a block of memory of the specified size, calloc() initializes dynamically allocated memory to zero, and realloc() resizes an existing block of memory.

  1. What is the best practice for handling memory allocation errors in C?

The best practice is to check if malloc(), calloc(), or realloc() returns NULL and handle the error gracefully by printing an error message and exiting the program.