Freeing an Object from Memory Explicitly
Contents
3.1. Freeing an Object from Memory Explicitly#
In the previous chapter, we discuss that when an object is created, the constructor is called, and when it goes out of scope, the destructor is called automatically. However, in another case, if the object was dynamically allocated, the destructor is explicitly called when an object is freed. We need to recap dynamic memory allocation before we look at an example of this case.
3.1.1. Recap: Dynamic Memory Allocation#
What happens when a program runs? A computer allocates memory in Random Access Memory (RAM) (or another named is main memory) for the program’s variables and objects. There are four segments in this memory:
Stack: Stores the local variables and objects of a function
Heap: Stores the dynamically allocated memory,
Globals + Const variables: Stores the constants and global variables of your program
Code: Stores the instructions of the program
In the following example, we will see the stack used to store local variables and the heap storing dynamically allocated memory.
3.1.1.1. Step 1: Stack Only#
In Fig. 3.1, in the first two lines, we declare and initialize x
to 10 and declare and initialize pointer p
of type int*
to NULL
. Both x
and p
are stored in the stack as they are local variables.
In p = &x
, we use the reference operator &
before x
to get the address of x
and we store it in p
. Using p
, we can now gain access to x
.
In *p = 5
, we use the deference operator *
before p
to dereference it, which means we access the value stored at the address that p
points to. We can say “we dereference the reference to x
,” which is x
. This changes the line *p = 5
\(\rightarrow\) *(&x) = 5
\(\rightarrow\) x = 5
, allowing allows us to change the value of x
to 5.
Code in main.cpp

Fig. 3.1 The stack stores local variables: int x
and int* p
, where p
stores the address of x
in the stack, and then through p
we change the value of x
from 10 to 5.#
3.1.1.2. Step 2: Dynamic Memory Allocation#
In Fig. 3.2, we dynamically allocate memory for an integer using the new
operator. The new
operator allocates memory on the heap, and it returns the address to that memory. Hence, in p = new int
, p
now points to the heap memory where the integer is stored. We can access the value stored in that memory using *p
.
In *p = 20
, we again dereference p
to change the value stored in the heap memory to 20.
Code in main.cpp

Fig. 3.2 Dynamically allocating memory using new
operator. The pointer p
now points to the heap memory where the integer is stored, and we can access it using *p
.#
3.1.1.3. Step 3: Freeing Memory#
In Fig. 3.3, we free the dynamically allocated memory using the delete
operator. After the delete
operator we write the variable that stores the address on the heap, i.e. p
. After this line, p
still points to the same address, but that memory is no longer valid for use, and accessing it will lead to undefined behavior. p
is now called a dangling pointer. This memory location is “freed” as shown in the image.
Code in main.cpp

Fig. 3.3 We free the dynamically allocated memory using the delete
operator. This frees the memory back to the heap.#
3.1.1.4. Step 4: Resolve Dangling Pointer#
To resolve the dangling pointer issue, we set p
to NULL
after freeing the memory. This way, we can check if p
is NULL
before dereferencing it in the future, preventing undefined behavior.
Code in main.cpp

Fig. 3.4 It’s a good practice to always set the pointer to NULL
after freeing the memory to avoid dangling pointer issues.#
3.1.1.5. Dynamic Memory Allocation of Arrays#
To dynamically allocate an integer, we use
new int
, but to dynamically allocate an array of integers, we use
new int[size]
, where size
is the number of elements in the array. The new
operator allocates memory for the array on the heap and returns a pointer to the first element of the array.
For freeing, to free the dynamically allocated integer that was allocated using int* p = new int
, we use
delete p;
To free the dynamically allocated array that was allocated using int* p = new int[size]
, we use
delete[] p;
Notice the []
after delete
, which indicates that we are freeing an array. This is important to ensures that entire array is freed.
3.1.2. Explicitly Calling Destructor#
Objects can also be dynamically allocated using the new
operator. When an object is created dynamically, its constructor is called. For example, if we have a class named Student
, we can dynamically allocate an object and store its address in a pointer p
using
Student* p = new Student;
However, to free the memory of the object, the destructor is explicitly called when the delete
operator is used. For example, the following line will call the destructor of the Student
class:
delete p;
You can try out the following code to see how the constructor and destructor are called when an object is dynamically allocated and freed.
Code in main.cpp
#include <iostream> using namespace std;
class Student { public: Student() { cout << "Constructor called" << endl; } ~Student() { cout << "Destructor called" << endl; } }; int main(void) { Student* p = new Student; // Dynamically allocated object delete p; // Explicitly calling destructor return 0; }