I am making an attempt to build my library of elementary operations for linked list but I get into trouble with the function push_back()
which works: Push the data at the end of the linked list.
Here is my source code:
node* push_back(node *dir, item datain)
{
node *newnode = (node *)malloc(sizeof(node));
newnode->data = datain;
newnode->next = NULL;
if (dir == NULL)
{
dir = newnode;
}
else
{
while (dir->next != NULL)
dir = dir->next;
dir->next = newnode;
}
return dir;
}
void printlist(node *dir)
{
printf("%-50s%-50s%-20s\n", "Name", "Email", "Phone number");
while (dir != NULL)
{
item temp = dir->data;
printf("%-50s%-50s%-20s\n", temp.name, temp.email, temp.phone);
dir = dir->next;
}
}
int main()
{
node *dir = (node *) malloc(sizeof(dir));
dir = NULL;
int i = 0;
while(i<3)
{
item temp = userdata();
dir = push_back(dir, temp);
i++;
}
printlist(dir);
freelist(dir);
return 0;
}
My problem: If I just insert 2 records (each record has name, email and phone number), then it's ok. However, If there are more than 2 records, as I print the whole records I have inserted, it just print out the two lastest record. I have checked my code on some websites but I find that they bare no resemblance as mine. For example:
INPUT:
Enter the name: Joey
Enter the email: [email protected]
Enter the phone number: 0235632514
Enter the name: Mathew
Enter the email: [email protected]
Enter the phone number: 012502252
Enter the name: Waley
Enter the email: [email protected]
Enter the phone number: 036625125
OUTPUT:
Name Email Phone number
Mathew [email protected] 012502252
Waley [email protected] 036625125
First problem :
node *dir = (node *) malloc(sizeof(dir)); dir = NULL;
so you have a memory leak because you loose the allocation, just do
node *dir = NULL;
Second problem push_back returns the last element of the list so doing
dir = push_back(dir, temp);
dir now point to the last element and you lost the head of the list, so all elements except the last
One way is to modify push_back to return the (new) head of the list :
node* push_back(node * head, item datain)
{
node *newnode = (node *)malloc(sizeof(node));
newnode->data = datain;
newnode->next = NULL;
if (head == NULL)
return newnode;
node * dir = head;
while (dir->next != NULL)
dir = dir->next;
dir->next = newnode;
return head;
}
but that supposes the caller always does something like dir = push_back(dir, temp);
an other way is to use double pointer :
void push_back(node ** head, item datain)
{
node *newnode = (node *)malloc(sizeof(node));
newnode->data = datain;
newnode->next = NULL;
if (*head == NULL)
*head = newnode;
else {
node * dir = *head;
while (dir->next != NULL)
dir = dir->next;
dir->next = newnode;
}
}
and the caller can just do push_back(&dir, temp); without taking the risk to forget to assign