You can consider it as an brain twister if your not that familiar with dynamic memory allocation.
First save this code as a C program in your bin directory.
#include<stdio.h>
#include<conio.h>
struct node {
int data;
struct node *next;
} *head=NULL;
void ins_at_beg()
{
struct node *node=malloc(4);
node->next=head; head=node;
printf("Please enter the value to be inserted at the start: ");
scanf("%d",node); // POINT A
}
void ins_at_end()
{
struct node *node=head;
while(node->next) node=node->next;
node->next=malloc(4);
printf("Please enter the value to be inserted at the end: ");
scanf("%d",node->next->data); // POINT B
}
void main()
{
clrscr();
ins_at_end();
printf("%d",head->data);
getch();
}
Execute this code and everything shall seem fine.
Now after the program gets executed ins_at_end()
of the main function to ins_at_beg()
and execute the program, things shall still seem fine.
Now manually undo the above change (change ins_at_beg
to ins_at_end
) and execute the program. Now you'll get the value of head->data
as 0.
Now just change node
of 'Point A' to node->data
and you'll get to see that the entered value gets reflected on the screen (Note: We didn't call that function in the main function)
Now again reverse the above change and get 0 as the default value of head->data
.
The main thing to notice here is that the output gets changed by a function which is just defined and is not called in the main function.
Just play with it for a while and you'll get to know what am I trying to say.
Question: Why does the program work as normal when I change node
to node->data
even if I am not practically calling the function I made the change in in the main function?
This:
scanf("%d",node);
And this:
scanf("%d",node->next->data);
Are incorrect. The %d
format specifier expects an int *
as an argument. But instead you're passing in a struct node *
in one case and an int
in the other case. Using the wrong format specifier to scanf
invokes undefined behavior which is why you're seeing strange results.
You should be doing this:
scanf("%d",&node->data);
And this:
scanf("%d",&node->next->data);
Also, this makes assumptions about the size of a pointer:
struct node *node=malloc(4);
You should instead be doing:
struct node *node=malloc(sizeof(*node));
You've also got a problem here:
void ins_at_end()
{
struct node *node=head;
while(node->next) node=node->next; // <--- here
node->next=malloc(4);
printf("Please enter the value to be inserted at the end: ");
scanf("%d",node->next->data); // POINT B
}
At program startup, head
is NULL, so you're trying to dereference a NULL pointer which again causes undefined behavior. Check for this situation before you do anything else. Also, you should explicitly set the next
pointer at the end of the list to NULL.
void ins_at_end()
{
struct node *node=malloc(sizeof(*node));
struct node *tmp;
printf("Please enter the value to be inserted at the end: ");
scanf("%d",&node->data);
node->next = NULL;
if (!head) {
head = node;
} else {
tmp = head;
while (tmp->next) tmp = tmp->next;
tmp->next = node;
}
}