I have a C program to insert elements at the beginning of a linked list but when I try to print the elements it always skips the first element. Can someone please point out what I am doing wrong in my program.
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
void PrintElements();
void InsertElement(int x);
struct node
{
int data;
struct node* next;
};
struct node* HEAD;
struct node* temp;
struct node* temp1;
void PrintElements()
{
temp1=HEAD;
while(temp1->next!=NULL)
{
printf("\n\r Data %d\n\r",temp1->data);
printf("\n\r Address %x\n\r",temp1->next);
temp1=temp1->next;
}
}
void InsertElement(int x)
{
struct node* temp=(struct node*)malloc(sizeof(struct node));
temp->data=x;
temp->next=HEAD;
HEAD=temp;
}
int main()
{
int i, x;
int n; //n stores the number of elements to be added to the linked list
HEAD=NULL; //Assigning HEAD to null when there are no elements in the list
printf("Enter the number of elements\n");
scanf("%d",&n);
for(i=0;i<n;i++)
{
printf("\n\rEnter the number");
scanf("%d",&x);
InsertElement(x);
PrintElements();
}
return 0;
}
When I changed the following line
while(temp1->next!=NULL)
to
while(temp1!=NULL)
the program works correctly but I am still not able to understand why.
The problem that you describe can be fixed by changing the controlling expression in your
PrintElements()
function totemp1 != NULL
. This way, iftemp1
points to a node, thedata
andnext
fields are printed, and the loop continues until there are no more nodes. When iterating over a linked list, it usually seems to confuse things when you look at the next node to decide what you will do with the current node. But there are other problems with this code.First, it would be much better to declare the
struct
pointers inmain()
and pass them to the functions, instead of declaring them as global variables. You should check the return values of the functions that you call whenever possible. You should checkscanf()
to make sure that the input is as expected; this also provides a way to control the input loop, removing the need for the user to explicitly enter a count before inputting data. You should also check the value returned by calls tomalloc()
to catch allocation errors. Such an allocation error in your code would lead to undefined behavior whentemp
is dereferenced in the very next line.You should
free
all memory allocations, onefree()
for each call tomalloc()
. When you print the address of thenext
node in the list in the functionPrintElements()
, you invoke undefined behavior. To print the value of a pointer, you should use the%p
format specifier, and you must cast the pointer to(void *)
. Finally, there is no need to#include <malloc.h>
;stdlib.h
takes care of what you need.Here is a modified version of your code that implements the suggested changes. Note that in the event of an allocation error, a message is printed to
stderr
, and the programexit
s. The call tomalloc()
has been simplified: there is no reason to cast the result ofmalloc()
in C, and it is better to use the name of the pointer to which you are assigning the memory in place of an explicit type in the argument given tomalloc()
. Thenew_node
is returned to the calling function, where the pointer to thehead
of the list is reassigned to point to thenew_node
.