Back to C Programming
2026-07-156 min read

malloc()

Learn malloc() step by step with clear examples and exercises.

Why This Matters

In C programming, managing memory effectively is crucial for efficient code execution. The malloc() function allows you to dynamically allocate memory during runtime, which can be particularly useful when dealing with arrays or structures whose sizes are not known at compile time. Understanding how to use this function can help you avoid common pitfalls and write more robust programs.

This lesson will walk you through the ins and outs of using malloc(), including a worked example, common mistakes to watch out for, practice questions, and frequently asked questions. By the end, you'll have a solid understanding of dynamic memory allocation in C programming using malloc().

Prerequisites

Before diving into malloc(), ensure you have a good grasp of the following concepts:

  1. Basic C syntax and semantics
  2. Data types (int, char, float, etc.)
  3. Variables and constants
  4. Arrays
  5. Pointers
  6. Basic input/output functions (scanf(), printf())
  7. Structures
  8. Functions and function pointers

Core Concept

Allocating Memory with malloc()

The malloc() function is a library function that dynamically allocates memory during runtime. It takes one argument: the number of bytes you want to allocate. The returned pointer points to the first byte of the allocated memory block. Here's an example:

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

int main() {
int *ptr; // declare a pointer to an integer
int size = 10; // number of integers we want to store

ptr = (int *) malloc(size * sizeof(int)); // allocate memory for 10 integers

if (ptr == NULL) { // check if the allocation was successful
printf("Memory allocation failed.\n");
return 1;
}

// use the allocated memory
for (int i = 0; i < size; i++) {
ptr[i] = i * i; // store squares of numbers from 0 to 9
}

// print the contents of the allocated memory block
printf("Contents of the allocated memory:\n");
for (int i = 0; i < size; i++) {
printf("%d ", ptr[i]);
}

free(ptr); // deallocate the memory when done
return 0;
}

In this example, we first declare a pointer to an integer and specify the number of integers we want to store. Then, we use malloc() to allocate memory for those integers and store the returned pointer in our variable ptr. We check if the allocation was successful by comparing the returned pointer with NULL. If it's not NULL, we proceed to use the allocated memory block. After using the memory, we print its contents and deallocate it using the free() function.

Common Mistakes

  1. ### Forgetting to check if malloc() returned NULL

If memory allocation fails, malloc() returns NULL. Failing to check for this can lead to undefined behavior and program crashes.

  1. ### Not deallocating memory with free()

Failing to deallocate allocated memory using the free() function can cause a memory leak, which can lead to program instability or even system crashes.

  1. ### Using freed memory again

After deallocating memory with free(), it's essential not to use that memory again until you re-allocate it. Doing so can result in undefined behavior and potential security vulnerabilities.

  1. ### Not accounting for the size of pointers

When calculating the number of bytes to allocate, don't forget to include the size of pointers. For example, if you want to allocate memory for an array of 10 integers, you should use size * sizeof(int) + sizeof(int *) to account for the pointer itself.

Worked Example

Let's work through a more complex example that demonstrates using malloc() with structures and dynamically-sized arrays.

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

typedef struct {
char name[50];
int age;
} Person;

void read_person(Person *person) {
printf("Enter name: ");
fgets(person->name, sizeof(person->name), stdin);
person->name[strcspn(person->name, "\n")] = '\0'; // remove newline character
printf("Enter age: ");
scanf("%d", &person->age);
}

int main() {
Person *people; // declare a pointer to an array of Persons
int num_people, i;

printf("Enter the number of people: ");
scanf("%d", &num_people);

people = (Person *) malloc(num_people * sizeof(Person)); // allocate memory for an array of Persons

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

for (i = 0; i < num_people; i++) {
read_person(&people[i]); // read each person's data
}

// print the contents of the allocated memory block
printf("\nList of people:\n");
for (i = 0; i < num_people; i++) {
printf("Person %d:\n", i + 1);
printf("Name: %s\n", people[i].name);
printf("Age: %d\n", people[i].age);
}

free(people); // deallocate the memory when done
return 0;
}

In this example, we define a Person structure and a function called read_person() to read data for each person. We then allocate memory for an array of num_people Person structures using malloc(). After reading the data for each person and printing the list of people, we deallocate the memory with free().

Common Mistakes

  1. ### Not accounting for the size of the structure when allocating memory

When allocating memory for an array of structures, don't forget to include the size of each structure in your calculation. For example, if you have a Person structure with two fields (name and age), and you want to allocate memory for 10 people, use num_people * sizeof(Person).

  1. ### Not checking the return value of read_person()

In the worked example, we assume that read_person() always returns successfully. However, if it encounters an error (such as a failed input), it should return an error code or set a global variable to indicate failure. The main function should then check for this error before proceeding with further processing.

Practice Questions

  1. Write a program that uses malloc() to create a dynamic array of integers and finds the maximum element in the array.
  2. Modify the worked example to handle errors when reading data for each person (e.g., invalid input or out-of-range age).
  3. Write a program that dynamically allocates memory for a two-dimensional array (array of arrays) of integers and performs basic operations like finding the sum, minimum, and maximum elements in the array.
  4. Write a function called copy_person() that takes a Person structure as an argument and returns a new Person structure with the same data. Use malloc() to allocate memory for the new structure.

FAQ

### What happens if I forget to free() allocated memory?

If you forget to deallocate memory using free(), it can lead to a memory leak, which can cause your program to consume more resources than necessary and potentially crash or slow down the system over time.

### Can I use malloc() to allocate memory for strings?

Yes! You can use malloc() to dynamically allocate memory for strings. Just remember to include the null terminator (\0) at the end of the string and account for its size when calculating the total number of bytes needed.

### Is it safe to mix malloc() and array indexing?

Mixing malloc() and array indexing can be dangerous because you might access memory outside the allocated block, leading to undefined behavior. Always use a pointer to access dynamically-allocated memory, and ensure that you don't exceed the bounds of your allocated memory.

### Can I use malloc() for character arrays (char arrays)?

Yes! You can use malloc() to allocate memory for character arrays (also known as strings or C-strings). Just remember to include the null terminator (\0) at the end of the string and account for its size when calculating the total number of bytes needed.