How to Release the Allocated Memory for Nodes in the Linked List in C
Today, we will see how to free or release the allocated memory for nodes in the linked list in C.
Release the Allocated Memory for Nodes in the Linked List in C
In this article, we are using the free()
function to release the memory that was reserved or allocated by the malloc()
function. It means that whenever we call the malloc()
function, we must call the corresponding free()
function at some point to release the memory.
While using the linked list in C programming, every node of a linked list is assigned a memory as soon as the malloc()
function is called. Therefore, we release the allocated memory by calling the free()
method whenever the node or complete linked list is no longer needed.
Suppose we have a linked list containing the 3 nodes, and we decided that this linked list is not required now. We can use the loop to iterate over the linked list and free the allocated memory for each node.
Remember, we cannot expect the whole structure of a linked list to be freed by calling the free()
function from the root node. To understand it practically, we are using two code examples.
- Print a complete linked list and release the allocated memory for all nodes
- Print the current node, save the pointer of the next node, and free the memory for the current node. This means we are printing and releasing the allocated memory in one loop.
Print the Entire Linked List and Release the Allocated Memory
To learn this scenario practically, we define the linked list nodes as follows. Notice that we define the structure in the recursive manner, which C programming allows.
Further, we are using the typedef struct
instead of struct
only to write a more organized and clean code. The difference between the typedef struct
and struct
is explained in detail here.
typedef struct node {
int data;
struct node* next;
} nodes;
Populate all the nodes using the makeList()
function. Here, we have only three nodes in the linked list.
struct node* makeList() {
nodes* headNode = NULL;
nodes* secondNode = NULL;
nodes* thirdNode = NULL;
headNode = malloc(sizeof(nodes));
secondNode = malloc(sizeof(nodes));
thirdNode = malloc(sizeof(nodes));
headNode->data = 1;
headNode->next = secondNode;
secondNode->data = 2;
secondNode->next = thirdNode;
thirdNode->data = 3;
thirdNode->next = NULL;
return headNode;
}
The printList()
method (below) iterates over the linked list and prints every list node. Here, we created the currentNode
that references the headNode
.
Then, we use a while
loop to check if the currentNode
is NULL
. If not, then print the currentNode
data and save the next node’s address in currentNode
.
This process continues until the currentNode
equals the NULL
.
void printList(nodes* headNode) {
nodes* currentNode = headNode;
while (currentNode != NULL) {
printf("The current element is %d\n", currentNode->data);
currentNode = currentNode->next;
}
}
After printing the entire linked list, the freeList()
function (below) releases the allocated memory for each node.
The freeList()
function checks if the headNode
is NULL
. If it is NULL
, the list is empty, so we immediately return from this function.
Secondly, save the headNode
in a currentNode
variable, and make the headNode
point to the immediate next node in our list. We are doing it in headNode = headNode->next;
.
Thirdly, we safely release the allocated memory using free(currentNode)
. Now, the headNode
points to the remaining list and goes back to the first step.
void freeList(nodes* headNode) {
nodes* currentNode;
while (headNode != NULL) {
currentNode = headNode;
headNode = headNode->next;
free(currentNode);
}
}
Finally, we use the main()
method to call the functions as follows and accomplish the goal.
int main() {
nodes* headNode = makeList();
printList(headNode);
freeList(headNode);
return 0;
}
Complete Example Code
The whole program looks as shown below when we assemble all the code chunks.
#include <stdio.h>
typedef struct node {
int data;
struct node* next;
} nodes;
struct node* makeList() {
nodes* headNode = NULL;
nodes* secondNode = NULL;
nodes* thirdNode = NULL;
headNode = malloc(sizeof(nodes));
secondNode = malloc(sizeof(nodes));
thirdNode = malloc(sizeof(nodes));
headNode->data = 1;
headNode->next = secondNode;
secondNode->data = 2;
secondNode->next = thirdNode;
thirdNode->data = 3;
thirdNode->next = NULL;
return headNode;
}
void printList(nodes* headNode) {
nodes* currentNode = headNode;
while (currentNode != NULL) {
printf("The current element is %d\n", currentNode->data);
currentNode = currentNode->next;
}
}
void freeList(nodes* headNode) {
nodes* currentNode;
while (headNode != NULL) {
currentNode = headNode;
headNode = headNode->next;
free(currentNode);
}
}
int main() {
nodes* headNode = makeList();
printList(headNode);
freeList(headNode);
return 0;
}
Output:
The current element is 1
The current element is 2
The current element is 3
Print the Current Node, Save the Pointer for the Next Node, and Free Allocated Memory for the Current Node
In this code example, we are printing the current node, saving the address for the next node, and releasing the allocated memory for the current node.
Everything is the same as in the previous example except for two things. First, we don’t have the freeList()
function and second, we have printAndFreeList()
instead of the printList()
.
In the printAndFreeList()
function, we are iterating over the list, printing the current node, saving the pointer for the rest of the linked list, and releasing the memory for the current node.
This process continues until the NULL
is found.
void printAndFreeList(nodes* currentNode) {
nodes* tempNode;
while (currentNode != NULL) {
tempNode = currentNode;
printf("The current element is %d\n", currentNode->data);
currentNode = currentNode->next;
free(tempNode);
}
}
Complete Example Code
The whole program looks as follows.
#include <stdio.h>
typedef struct node {
int data;
struct node* next;
} nodes;
struct node* makeList() {
nodes* headNode = NULL;
nodes* secondNode = NULL;
nodes* thirdNode = NULL;
headNode = malloc(sizeof(nodes));
secondNode = malloc(sizeof(nodes));
thirdNode = malloc(sizeof(nodes));
headNode->data = 1;
headNode->next = secondNode;
secondNode->data = 2;
secondNode->next = thirdNode;
thirdNode->data = 3;
thirdNode->next = NULL;
return headNode;
}
void printAndFreeList(nodes* currentNode) {
nodes* tempNode;
while (currentNode != NULL) {
tempNode = currentNode;
printf("The current element is %d\n", currentNode->data);
currentNode = currentNode->next;
free(tempNode);
}
}
int main() {
nodes* headNode = makeList();
printAndFreeList(headNode);
return 0;
}
Output:
The current element is 1
The current element is 2
The current element is 3