Unexpected output while printing a linked list - c

I got this code on codeblocks 13.12 in lubuntu 16.04
The program is running but the problem is that the first insertion is duplicated that is,
lets say i first insert integer "4" to the linked list. But i get the output as:
4 ,4 ,
#include <stdio.h>
#include <stdlib.h>
struct node {
int data;
struct node* next;
};
struct node* head = NULL;
void Insert(int c)
{
if(head == NULL) {
struct node* temp = malloc(sizeof(struct node));
temp -> data = c;
temp -> next = NULL;
head = temp;
}
struct node* temp = malloc(sizeof(struct node));
temp -> data = c;
temp -> next = NULL;
struct node* temp1 = head;
while (temp1->next != NULL) {
temp1 = temp1->next;
}
temp1 -> next = temp;
}
void print() {
struct node* temp = head;
printf("list is: \n");
while (temp != NULL) {
printf( "%d ,",temp->data);
temp = temp->next;
}
}
int main () {
printf("How Many Numbers?\n");
int a ,b ,c;
scanf("%d" , &b);
for(a = 0;a<b;a++) {
printf("Enter the numbers \n");
scanf("%d",&c);
Insert(c);
print();
}
return 0;
}

the problem is that the first insertion is duplicated
Reason:
You've mentioned if(head==NULL) correctly to check whether inserted node is first node or not but after this you did not mention else to restrict compiler.
So the compiler compiles both the if block and the code following it
So another node gets created after head with the same value c
that's the reason when you insert c=4, you get 4,4, as output
Solution
Try using your insert() with an else condition as
void Insert(int c)
{
if(head == NULL)
{
struct node* temp = malloc(sizeof(struct node));
temp -> data = c;
temp -> next = NULL;
head = temp;
}
else
{
struct node* temp = malloc(sizeof(struct node));
temp -> data = c;
temp -> next = NULL;
struct node* temp1 = head;
while (temp1->next!= NULL)
temp1 = temp1->next;
temp1 -> next = temp;
}
}
suggestion : you've mentioned this twice in you insert() function
struct node* temp = malloc(sizeof(struct node));
temp -> data = c;
temp -> next = NULL;
just allocate temp once and then insert it at approprite position using if-else conditions. This reduces the number of lines of code too. do it this way:
void Insert(int c)
{
struct node* temp = malloc(sizeof(struct node));
temp -> data = c;
temp -> next = NULL;
if(head == NULL)
{
head = temp;
}
else
{
struct node* temp1 = head;
while (temp1->next!= NULL)
temp1 = temp1->next;
temp1 -> next = temp;
}
}

That is because the Insert function "falls through" after initialising the first item, and inserts it again. Add return at the end of the code block.
void Insert(int c)
{
if(head == NULL) {
struct node* temp = malloc(sizeof(struct node));
temp -> data = c;
temp -> next = NULL;
head = temp;
return; //<-- add this line
}
...

Related

C programming - Reverse a linked link by iterative method

I am trying to reverse a linked by iterative method. Magically, after watching tutorial and trying to recode myself, the program works successfully. However, when I review the code, I hit a question: in line 23, why we must use temp1->next instead of temp1? When traversing to the end of the linked list, which case we use the condition (the node != NULL)? In which case we use (the link of the node ! = NULL)? I fully appreciate it if anyone can enlighten me.
#include <stdio.h>
#include <stdlib.h>
struct Node
{
int data;
struct Node* next;
};
struct Node* Insert(struct Node* head, int data)
{
struct Node* temp = (struct Node*) malloc(sizeof(struct Node));
temp->data = data;
temp->next = NULL;
//If the list is empty
if (head == NULL)
{
head = temp;
}
else //The list is not empty
{
struct Node* temp1 = head;
while (temp1->next != NULL)
{
temp1 = temp1->next;
}
temp1->next = temp;
}
return head;
}
void Print(struct Node* head)
{
struct Node* temp = head;
while (temp != NULL)
{
printf("%d ", temp->data);
temp = temp->next;
}
printf("\n");
}
struct Node* Reverse(struct Node* head)
{
struct Node* *prev, *current, *next;
current = head;
prev = NULL;
while (current != NULL)
{
next = current->next;
current->next = prev;
prev = current;
current = next;
}
head = prev;
return head;
}
int main()
{
struct Node* head = NULL;
printf("Enter the length of the linked list you want to create: ");
int length;
scanf("%d", &length);
printf("Enter the value you want to input: ");
int i;
for (i = 0; i < length; i++)
{
int x;
scanf("%d", &x);
head = Insert(head, x);
}
printf("Given linked list\n");
Print(head);
head = Reverse(head);
printf("\nReversed linked list \n");
Print(head);
return 0;
}
In that case, inside the while condition, on line 23, you can notice that the program is using temp1 = temp1->next, if you change the condition to temp1 != NULL when it reaches the last element of linked list it'll collect trash from memory or even result in an error, because NULL don't have a next position.
So, you use temp1 != NULL if you are accessing the data inside the list and temp1->next != NULL if you are manipulating the next positions of the linked list.
Because temp1->next at the end of the linked list is NULL, however, the last node has data, if you use temp1 == NULL you would say that the last node is NULL, which is not the case. So you want to end the loop when the "pointer to the next node" is NULL, not when the next node is NULL.

Linked List using recursion - Unexpected Output

I found this on Internet to reverse a list using recursion and applied it in codeblocks but the output only reverse prints last two Insert call from main function. It skips the first three Insert calls. Why? I did search for this problem here but I failed to understand them as I'm a beginner. Kindly help
#include <stdio.h>
#include <stdlib.h>
struct Node
{
int data;
struct Node* next;
};
struct Node * head;
struct Node* Insert (struct Node* head, int data)
{
struct Node* temp = (struct Node*)malloc(sizeof(struct Node));
temp->data = data;
temp->next = NULL;
if(head == NULL)
{
head = temp;
return;
}
struct Node* temp2 = head;
while(temp2->next != NULL)
{
temp2 = temp2->next;
}
temp2->next = temp;
}
void reversePrint(struct Node* head)
{
if(head == NULL)
{
printf("\n");
return;
}
reversePrint(head->next);
printf(" %d ", head->data);
return;
}
int main()
{
struct Node* head = NULL;
head = Insert(head,2);
head = Insert(head,7);
head = Insert(head,3);
head = Insert(head,1);
head = Insert(head,4);
reversePrint(head);
return 0;
}
O/P : 4 1
NOTES:
Don't cast the return of value of malloc
You declared two *head and confused yourself
No need to pass pointer to function and return pointer when you have head declared as global. Which is not a good idea but I followed your code.
Code:
#include <stdio.h>
#include <stdlib.h>
struct Node
{
int data;
struct Node* next;
};
struct Node * head;
void Insert (int data)
{
struct Node* temp = malloc(sizeof(struct Node));
temp->data = data;
temp->next = NULL;
if(head == NULL)
{
head = temp;
return;
}
struct Node* temp2 = head;
while(temp2->next != NULL)
{
temp2 = temp2->next;
}
temp2->next = temp;
}
void reversePrint(struct Node* head)
{
if(head == NULL)
{
printf("\n");
return;
}
reversePrint(head->next);
printf(" %d ", head->data);
return;
}
int main()
{
Insert(2);
Insert(7);
Insert(3);
Insert(1);
Insert(4);
reversePrint(head);
return 0;
}
OUTPUT:
4 1 3 7 2

Segmentation Fault on Linked List Using C

I am new to C and try to learn how to implement C on linked list. I am really confused why I can't access myList in the main function? because when I try to myList->data, it's segmentation fault. I think there's some error in my addtohead function?
Below is my code:
#include <stdio.h>
#include <stdlib.h>
typedef struct NODE{
int data;
struct NODE *next;
}node;
node * myList;
node * addToHead(node*, int);
void printList();
int main(){
myList = NULL;
int input;
while (scanf("%i",&input) == 1){
addToHead(myList, input);
printf("%d \n", myList->data);
}
printf("My List:\n");
printList(myList);
return 0;
}
node* addToHead(node* head, int newData){
node *temp = (node *)malloc(sizeof(node));
temp -> data = newData;
temp -> next = NULL;
if(head != NULL){
temp -> next = head;
}
head = temp;
return head;
}
void printList(node* head){
node *temp = head;
while(temp != NULL){
printf("%d ", temp->data);
temp = temp -> next;
}
printf("\n");
}
Your addToHead function is supposed to return the mallocated memory back to caller.
So you should assign the return value to mylist at first:
int main(){
node *myList = NULL;
int input;
while (scanf("%i",&input) == 1){
myList = addToHead(myList, input);
printf("%d \n", myList->data);
}
printf("My List:\n");
printList(myList);
return 0;
}
Into your addToHead function you wrote
head = temp;
But head has local scope and the assigned value is not reflected to the pointer myList.
To do so you have to use pointer to pointer.
int main(){
node *myList = NULL;
int input;
while (scanf("%i",&input) == 1)
{
if (addToHead(&myList, input) == true)
{
printf("%d \n", myList->data);
}
else
{
fprintf(stderr, "Error addToHead\n");
}
}
return 0;
}
bool addToHead(node** head, int newData){
node *temp = malloc(sizeof(node));
if (temp != NULL)
{
temp -> data = newData;
temp -> next = NULL;
if(head != NULL)
{
temp -> next = *head;
}
*head = temp;
return true;
}
return false;
}
Finally always remember to check the malloc return value: it can fail.
You return the new head node from addToHead, but you don't do anything with it. You need to assign this value to myList to update it:
myList = addToHead(myList, input);
Also, you misspelled a variable on the following line:
printf("%d \n", myListd->data);
It should be:
printf("%d \n", myList->data);
In this function definition
node* addToHead(node* head, int newData){
node *temp = (node *)malloc(sizeof(node));
temp -> data = newData;
temp -> next = NULL;
if(head != NULL){
temp -> next = head;
}
head = temp;
return head;
}
The parameter node* head is a local variable of the function. Any changes of the parameter will not influence on the original argument. The function parameters will be destroyed after exiting the function.
You can consider the function definition and its call the following way
addToHead(myList, input);
//...
node* addToHead(/*node* head, int newData*/){
node *head = myList;
int newData = input;
node *temp = (node *)malloc(sizeof(node));
temp -> data = newData;
temp -> next = NULL;
if(head != NULL){
temp -> next = head;
}
head = temp;
return head;
}
So the original variable myList will not be changed after the function call. You have to assign explicitly the returned value to the variable
myList = addToHead(myList, input);
Also the function has a drawback. It does not report an error in case when the new node was not allocated.
A better approach to write the function looks the following way
int /* _Bool */ addToHead( node **head, int newData )
{
node *temp = ( node * )malloc( sizeof( node ) );
int /* _Bool */ success = temp != NULL;
if ( success )
{
temp -> data = newData;
temp -> next = *head;
*head = temp;
}
return success;
}
In this case the function can be called in a loop the following way
while ( scanf( "%i", &input ) == 1 && addToHead( &myList, input ) )
{
//...
}

struct undeclared (first use in this function)

I'm very new to programming and I started to learn C. Now I just cant understand why my node structure is not visible to my functions.
I try to get some help on http://www.cprogramming.com/tutorial/c/lesson7.html
but with no luck in using code blocks 13.12
#include <stdio.h>
#include <stdlib.h>
struct node {
int data;
struct ptr * next;
};
struct node* head;
void Insert(int x)
{
struct node *temp;
temp = (node*)malloc(sizeof(struct node));
if(head == NULL)
head = temp;
temp->data = x;
temp->data = x;
temp->next = NULL;
struct node* temp1 = head;
while(temp1-> != NULL;) {
temp1 = temp1->next;
}
temp1->next = temp;
}
void print() {
struct node* temp = head;
while(temp != NULL) {
printf("the data is %d", temp->data);
temp = temp->next;
}
}
int main ()
{
head = NULL;
int a,c;
printf("How many numbers ? : \n");
scanf("%d",&a);
for(i = 0; i<a; i++); {
printf("Enter a number:\n");
scanf("%d",&c);
Insert(c);
print();
}
}
There are quite a few lets go one by one
number 1
struct node {
int data;
struct node *next; // chagnge ptr -> node
};
number 2
struct node *temp;
temp = malloc(sizeof(struct node)); // struct node casting
number 3
while(temp1->next != NULL) { // remove semi colum and put a next
temp1 = temp1->next;
}
number 4
int i; // for while loop
for(i = 0; i<a; i++) {
Now hopefully it compiles well, check runtime errors ( if any )
and yes
return 0; // just before main
you are building an infinite loop with your first element:
temp = (struct node*)malloc(sizeof(struct node));
if(head == NULL)
head = temp;
temp->data = x;
temp->next = NULL;
struct node* temp1 = head;
while(temp1->next != NULL) { // nothing to do
temp1 = temp1->next;
}
temp1->next = temp; //temp is head and temp1 is head, so head->next points to head
you should do something like
if (head == NULL) {
//fill head and leave
} else {
//traverse to the last element and concatenate the new element
}

Segmentation fault while implementing linked list in C

I'm trying to create a simple linked list and insert a node at the end of the list. I'm getting a segmentation fault.
#include <stdio.h>
#include <stdlib.h>
struct node{
int data;
struct node *link;
};
void create(struct node *head){
struct node* second = NULL;
struct node* last = NULL;
second = (struct node*)malloc(sizeof(struct node));
last = (struct node*)malloc(sizeof(struct node));
second -> data = 2;
last -> data = 3;
head -> link = second;
second -> link = last;
last -> link = NULL;
}
void insert_ending(struct node *head){
struct node* temp = NULL;
struct node* temp1 = NULL;
temp1 = (struct node*)malloc(sizeof(struct node));
temp1 -> data = 5;
temp1 -> link = NULL;
temp = head;
while(temp != NULL){
temp = temp -> link;
}temp -> link = temp1;
}
void PrintList(struct node *head){
while( head != NULL ){
printf(" %d -->", head -> data);
head = head -> link;
}
printf("\n");
}
int main(){
struct node* head = NULL;
head = (struct node*)malloc(sizeof(struct node));
head -> data = 1;
head -> link = NULL;
create(head);
PrintList(head);
insert_ending(head);
PrintList(head);
return 0;
}
I'm getting a segmentation fault. The output is as follows.
1 --> 2 --> 3 -->
Segmentation fault (core dumped)
in your insert function you need to change to :
temp = head;
while(temp -> link != NULL){
temp = temp -> link;
}
temp -> link = temp1;
the reason is that when you loop with while until temp == null, you can't afterward do: temp -> link because temp is allready null.
In the function 'insert_ending' in the while loop you want to change the
condition from:
while ( temp != NULL )
to:
while ( temp->link != NULL )
because now once the loop is finished, temp is NULL and then you try to dereference it (a NULL pointer) and get an error.

Resources