In C language, we can also create a generic linked list using the void pointer. Generic linked list means that it can store any data type as per the requirements.
The most important thing about the void pointer, it can store the address of any data type. Means that the programmer can store the address of any data type as per there the user requirements.
In the below example, I am creating a Node that contains the void pointer to store the address of any data type and Node pointer to create a link with another node.
Generic Node in C
Using the void pointer, we can create a generic Node. In the below source code I am creating a structure that contains the void pointer and structure pointer.
//Creating a new type
typedef void * pVoid;
// Creating Node
struct Node
{
/*void pointer*/
pVoid iData;
/*Node Pointer*/
struct Node *pNextNode;
};
// Define the new type Node type and Node pointer
typedef struct Node NodeType, * NodePointer;
Function to add a node at the end of the Generic Linked list
It creates an extra node and adds this node in the last of the generic linked list.
/* Paas the reference of the head pointer of a list and
an integer data. This function use to add the node at the End*/
int InsertNodeAtEnd(NodePointer * pHead, void *InputData, int SizeofData)
{
int iRetValue = -1;
int iOffSet = 0;
NodePointer pLastNode = NULL;
NodePointer pNewNode = NULL;
//Give the Address of first Node
pLastNode = *pHead;
// Call malloc to allocate memory in heap for the new node
pNewNode = malloc(sizeof(NodeType));
if( pNewNode != NULL) //Check allocated memory
{
pNewNode->iData = malloc(SizeofData); //put the desire Data
//Copy the bytes of data as per the data types
for (iOffSet = 0; iOffSet < SizeofData; iOffSet++)
*((uint8_t *)(pNewNode->iData + iOffSet)) = *((uint8_t *)(InputData + iOffSet));
pNewNode->pNextNode = NULL; //Give the Address of first Node
iRetValue = 0; // Update the return value
}
// If there is no node in beginning
if(pLastNode == NULL)
{
*pHead = pNewNode;
}
else
{
// Find the address of last node
while( pLastNode ->pNextNode != NULL)
{
pLastNode = pLastNode ->pNextNode;
}
// Assign last node address
pLastNode ->pNextNode = pNewNode;
}
return iRetValue;
}
Free the all allocated memory
We know that when we allocate memory in heap then this memory alive till the life of the program. So after use of this memory, we have to free all the allocated memory either we will get memory leak issues.
/* Paas the reference of the head pointer of a list. This function use
to free the all allocated memory*/
void FreeAllocatedMemory(NodePointer *pHead)
{
NodePointer pTmpNode = NULL;
NodePointer pFirstNode = NULL;
//Assign the Address of first node
pFirstNode = *pHead;
/*check if pFirstNode is NULL, then now list is empty,
so assign NULL to head and return.*/
while (pFirstNode != NULL)
{
/*Save the pFirstNode in a pTmpNode node pointer*/
pTmpNode = pFirstNode ;
/*Assign the address of next on your list*/
pFirstNode = pFirstNode->pNextNode;
//Free the data
free(pTmpNode->iData);
//Free the allocated memory
free(pTmpNode );
}
//Assign NULL to the head pointer
*pHead = NULL;
}
If you want to learn more about the c language, here 10 Free days (up to 200 minutes) C video course for you.
Your free trial is waiting
Driver program to create a generic linked list
In the below program user can create a linked-list as per their requirements. If the user selects 1 then the program creates a list of a character and if select 2 then create a list of an integer and if the user select 3 then create a list of the float.
#include<stdio.h>
#include<stdlib.h>
#include <stdint.h>
//Calculate size of buffer element
#define DATA_SIZE(y) sizeof(y[0])
//Calculate number of element in buffer
#define Number_Node(x) sizeof(x)/DATA_SIZE(x)
//Creating a new type
typedef void * pVoid;
// Creating Node
struct Node
{
/*void pointer*/
pVoid iData;
/*Node Pointer*/
struct Node *pNextNode;
};
//Define the new type Node type and Node pointer
typedef struct Node NodeType, * NodePointer;
//Print character
void PrintTheCharater(NodePointer pNode)
{
//Clear the screen
printf("\nLinked List is: \n\n");
while (pNode != NULL)
{
printf("\n %c\n\n",*((char *)pNode->iData));
pNode = pNode->pNextNode;
}
system("pause");
}
//Print integer
void PrintTheInteger(NodePointer pNode)
{
//Clear the screen
printf("\nLinked List is: \n\n");
while (pNode != NULL)
{
printf("\n %d\n\n",*((int *)pNode->iData));
pNode = pNode->pNextNode;
}
system("pause");
}
//Print float
void PrintTheFloat(NodePointer pNode)
{
//Clear the screen
printf("\nLinked List is: \n\n");
while (pNode != NULL)
{
printf("\n %f\n\n",*((float *)pNode->iData));
pNode = pNode->pNextNode;
}
system("pause");
}
/* Paas the reference of the head pointer of a list and
an integer data. This function use to add the node at the End*/
int InsertNodeAtEnd(NodePointer * pHead, void *InputData, int SizeofData)
{
int iRetValue = -1;
int iOffSet = 0;
NodePointer pLastNode = NULL;
NodePointer pNewNode = NULL;
//Give the Address of first Node
pLastNode = *pHead;
// Call malloc to allocate memory in heap for the new node
pNewNode = malloc(sizeof(NodeType));
if( pNewNode != NULL) //Check allocated memory
{
pNewNode->iData = malloc(SizeofData); //put the desire Data
//Copy the bytes of data as per the data types
for (iOffSet = 0; iOffSet < SizeofData; iOffSet++)
{
*((uint8_t *)(pNewNode->iData + iOffSet)) = *((uint8_t *)(InputData + iOffSet));
}
pNewNode->pNextNode = NULL; //Give the Address of first Node
iRetValue = 0; // Update the return value
}
// If there is no node in beginning
if(pLastNode == NULL)
{
*pHead = pNewNode;
}
else
{
// Find the address of last node
while( pLastNode ->pNextNode != NULL)
{
pLastNode = pLastNode ->pNextNode;
}
// Assign last node address
pLastNode ->pNextNode = pNewNode;
}
return iRetValue;
}
/* Paas the reference of the head pointer of a list. This function use
to free the all allocated memory*/
void FreeAllocatedMemory(NodePointer *pHead)
{
NodePointer pTmpNode = NULL;
NodePointer pFirstNode = NULL;
//Assign the Address of first node
pFirstNode = *pHead;
/*check if pFirstNode is NULL, then now list is empty,
so assign NULL to head and return.*/
while (pFirstNode != NULL)
{
/*Save the pFirstNode in a pTmpNode node pointer*/
pTmpNode = pFirstNode ;
/*Assign the address of next on your list*/
pFirstNode = pFirstNode->pNextNode;
//Free the data
free(pTmpNode->iData);
//Free the allocated memory
free(pTmpNode );
}
//Assign NULL to the head pointer
*pHead = NULL;
}
//Create a linked list of certain number of nodes
int CreateLinkedList(NodePointer *pHead, void *InputData, int SizeofData)
{
int iRetValue = -1;
int iOffSet = 0;
NodePointer pNewNode = NULL;
if((*pHead) == NULL)
{
// Call malloc to allocate memory in heap for the first node
pNewNode = malloc(sizeof(NodeType));
if( pNewNode != NULL) //Check allocated memory
{
pNewNode->iData = malloc(SizeofData); //put the desire Data
//Copy the bytes of data as per the data types
for (iOffSet = 0; iOffSet < SizeofData; iOffSet++)
{
*((uint8_t *)(pNewNode->iData + iOffSet)) = *((uint8_t *)(InputData + iOffSet));
}
pNewNode->pNextNode = NULL; //Give the Address of first Node
*pHead = pNewNode; /*Assign the address of
the first node to the head pointer*/
iRetValue = 0; // Update the return value
}
}
else
{
//Add the Node at the End
iRetValue = InsertNodeAtEnd(pHead,InputData,SizeofData);
}
return iRetValue;
}
int main(void)
{
int iRetValue = -1;
int iChoice = 0;
int iNumberNode =0;
int iCount = 0;
int iPosition =0;
/*Start with the empty list */
NodePointer head = NULL;
while(1)
{
//Clear the screen
system("cls");
//Select the Choice as per the requirements
printf("\n\n\
1: Create the Linked List of character\n\
2: Create the Linked List of integer\n\
3: Create the Linked List of float\n\
4: terminatethe process \n\n\n");
printf("\n\nenter your choice = ");
scanf("%d",&iChoice);
switch(iChoice)
{
case 1:
{
char acBuffer[4] = {'a','b','c','d'};
iNumberNode = Number_Node(acBuffer);
for(iCount =0; iCount <iNumberNode ; iCount++)
{
CreateLinkedList(&head, (acBuffer + iCount),DATA_SIZE(acBuffer));
}
PrintTheCharater(head);
break;
}
case 2:
{
int acBuffer[4] = {1, 2, 3, 4};
iNumberNode = Number_Node(acBuffer);
for(iCount =0; iCount <iNumberNode ; iCount++)
{
CreateLinkedList(&head, (acBuffer + iCount),DATA_SIZE(acBuffer));
}
PrintTheInteger(head);
break;
}
case 3:
{
float acBuffer[4] = {1.1, 2.2, 3.3, 4.4};
iNumberNode = Number_Node(acBuffer);
for(iCount =0; iCount <iNumberNode ; iCount++)
{
CreateLinkedList(&head, (acBuffer + iCount),DATA_SIZE(acBuffer));
}
PrintTheFloat(head);
break;
}
case 4:
{
printf("\n\nprocess is terminated\n ");
exit(1);
}
default:
{
printf("Invalid choice\n");
system("pause");
break;
}
}
//Free all allocated memory
FreeAllocatedMemory(&head);
}
return 0;
}
OutPut:
When user Enter: 1

When user Enter: 2

When user Enter: 3

When user Enter: 4

