Back to C++
2026-05-067 min read

C++ free()

Learn C++ free() step by step with clear examples and exercises.

Why This Matters

In this full guide, we delve deep into the free() function in C++, a fundamental aspect of memory management that every programmer should master. Understanding free() can help you avoid real-world bugs and perform better in interviews or exams. This guide covers not only the basics but also common mistakes, practice questions, and frequently asked questions to ensure a thorough understanding of this topic. Let's dive right in!

Prerequisites

To fully grasp this lesson, you should be familiar with the following concepts:

  1. Basic C++ syntax and programming constructs
  2. Data structures like arrays and pointers
  3. Understanding dynamic memory allocation using malloc(), calloc(), realloc(), and new/delete
  4. Familiarity with the standard template library (STL) containers such as vectors, lists, and arrays
  5. Concepts of object-oriented programming (OOP) and destructors
  6. Understanding pointers and references in C++
  7. Knowledge about error handling and exception safety

Core Concept

The free() function is a part of the C++ Standard Library, defined in the ` header file. Its primary purpose is to deallocate a block of memory previously allocated using malloc(), calloc(), or realloc()`. This makes the memory available for further allocations.

#include <iostream>
#include <cstdlib>

int main() {
int *arr = static_cast<int*>(malloc(10 * sizeof(int))); // Allocate an array of 10 integers

// Use the memory...

free(arr); // Deallocate the memory when done

return 0;
}

In the example above, we allocate an array of 10 integers using malloc(). After using the memory, we deallocate it using free(). It's essential to free allocated memory to avoid memory leaks.

Important Notes:

  • The free() function does not change the value of the pointer; it still points to the same memory location. This means that if you try to use the freed memory again, your program will likely crash or exhibit undefined behavior.
  • If you pass a null pointer (nullptr or 0) to free(), it does nothing and returns immediately.
  • Passing a pointer to memory not allocated by malloc(), calloc(), realloc(), or dynamically allocated using new can cause undefined behavior, which can lead to crashes or security vulnerabilities.

Core Concept - Dynamic Array Example

Let's create a simple program that demonstrates the use of free() with dynamic arrays. We will dynamically allocate an array, fill it with some values, and then deallocate the memory using free().

#include <iostream>
#include <vector>
#include <cstdlib>

int main() {
int *arr = static_cast<int*>(malloc(10 * sizeof(int))); // Allocate an array of 10 integers

std::fill(arr, arr + 10, 0); // Fill the array with zeros

for (size_t i = 0; i < 10; ++i) {
arr[i] = i * 2; // Modify the values in the array
}

for (size_t i = 0; i < 10; ++i) {
std::cout << arr[i] << " "; // Print the values in the array
}

free(arr); // Deallocate the memory when done

return 0;
}

In this example, we use std::fill from the STL to initialize the array with zeros. After filling and modifying the values in the array, we print them out before deallocating the memory using free().

Core Concept - Using new and delete

It's worth noting that C++ provides an alternative way of dynamic memory allocation using new and delete. However, these operators automatically call destructors for objects with a non-trivial constructor or destructor. In contrast, malloc(), calloc(), and realloc() do not invoke any constructors or destructors.

#include <iostream>
#include <vector>

int main() {
MyClass* arr = new MyClass[10]; // Allocate an array of 10 MyClass objects using new

// Use the memory...

delete[] arr; // Deallocate the memory when done

return 0;
}

In this example, we allocate an array of MyClass objects using new. When deallocating the memory with delete[], the destructor for each object is called automatically.

Worked Example

Let's create a simple program that demonstrates the use of smart pointers to manage dynamic memory allocation and deallocation in C++. We will dynamically allocate a vector of integers, fill it with random numbers, and then deallocate the memory using free().

#include <iostream>
#include <vector>
#include <random>
#include <cstdlib>
#include <memory>

int main() {
std::unique_ptr<int[], decltype(&free)> arr(static_cast<int*>(malloc(10 * sizeof(int))), free); // Allocate an array of 10 integers using malloc and a unique_ptr with a custom deleter

std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<> dis(0, 100);

std::fill(arr.get(), arr.get() + 10, 0); // Fill the array with zeros

for (size_t i = 0; i < 10; ++i) {
arr[i] = dis(gen); // Modify the values in the array
}

for (size_t i = 0; i < 10; ++i) {
std::cout << arr[i] << " "; // Print the values in the array
}

return 0;
}

In this example, we use a std::unique_ptr with a custom deleter to manage the dynamically allocated memory. When the unique_ptr goes out of scope, the memory will be automatically deallocated using the free() function.

Common Mistakes

  1. Forgetting to free allocated memory: Failing to deallocate memory after use can lead to memory leaks and other issues.
int *arr = static_cast<int*>(malloc(10 * sizeof(int))); // Allocate an array of 10 integers
// ...use the memory...
// Forget to free the memory!
  1. Using freed memory again: After calling free(), the pointer still points to the deallocated memory, which can lead to unexpected behavior or crashes.
int *arr = static_cast<int*>(malloc(10 * sizeof(int))); // Allocate an array of 10 integers
// ...use the memory...
free(arr); // Deallocate the memory
arr[0] = 42; // Using freed memory leads to undefined behavior!
  1. Not handling errors: When using dynamic memory allocation functions like malloc(), it's essential to check for errors and handle them appropriately, as these functions can return a null pointer if they fail to allocate memory.
int *arr = static_cast<int*>(malloc(10 * sizeof(int))); // Allocate an array of 10 integers
if (arr == nullptr) {
std::cerr << "Error allocating memory" << std::endl;
return 1;
}
// ...use the memory...
free(arr); // Deallocate the memory when done
  1. Passing a null pointer to free(): Although it does nothing, some programmers might forget and think they're causing an error.
int *arr = nullptr; // Initialize the pointer to null
free(arr); // Passing a null pointer is harmless but unnecessary
  1. Not using smart pointers: In modern C++, it's recommended to use smart pointers such as std::unique_ptr or std::shared_ptr to manage dynamic memory allocation and deallocation. These smart pointers automatically handle the lifetime of objects and provide additional benefits like exception safety and automatic memory management.

Practice Questions

  1. Write a program that dynamically allocates a character array, reads strings from the user until they enter an empty line, and then deallocates the memory using free().
  2. Modify the previous example to use calloc() instead of malloc(). Why is it necessary to call calloc() with an additional argument?
  3. What happens if you try to free a pointer that was not allocated using malloc(), calloc(), or realloc()?
  4. Write a program that dynamically allocates memory for a vector of integers, fills it with random numbers, and then deallocates the memory using free(). Use C++11 features such as ` and smart pointers (std::unique_ptr`).
  5. What is the difference between delete[] and free() when it comes to deallocating dynamically allocated arrays? When should you use each one?
  6. Write a program that demonstrates the use of realloc() and free(). How does realloc() behave when you try to reallocate memory for a pointer that was not previously allocated using malloc(), calloc(), or realloc()?
  7. What are some best practices for managing dynamic memory allocation in C++, and why are they important?

FAQ

  1. Why can't I use the delete[] operator instead of free() for arrays in C++?
  • In C++, you should always use delete[] to deallocate arrays, as it correctly calls the destructor for each element in the array. However, if you are writing a C-compatible program or need to work with code that uses malloc(), you can use free().
  1. Is it necessary to free memory allocated using new and delete?
  • No, memory allocated using new is automatically deallocated when the object goes out of scope or when you call delete. However, if you manually allocate memory with malloc(), calloc(), or realloc(), you should use free() to avoid memory leaks.
  1. Can I use free() on pointers returned by malloc_aligned() or posix_memalign()?
  • Yes, you can use free() to deallocate memory allocated using these functions as long as they were successfully initialized with the required alignment.
  1. What is the best practice for handling memory allocation and deallocation in C++?
  • In modern C++, it's recommended to use smart pointers such as std::unique_ptr or std::shared_ptr to manage dynamic memory allocation and deallocation. These smart pointers automatically handle the lifetime of objects and provide additional benefits like exception safety and automatic memory management.
  1. What are some common causes of memory leaks in C++ programs?
  • Memory leaks can occur when you forget to free dynamically allocated memory, return a pointer to dynamically allocated memory from a function without deallocating it, or use raw pointers instead of smart pointers. Proper memory management is crucial for writing efficient and robust code.
C++ free() | C++ | XQA Learn