Linked list program in C hangs - c

I am writing a linked list program
to add items and display those items.
I am able to add first item successfully,
but error occurs while adding the second item.
I tried to figure out the error,but
everything looks fine to me.
The program hangs,here is my code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct link_list
{
int number;
struct link_list *next;
};
typedef struct link_list node;
node *head;
void add(int num)
{
node *newnode,*current;
newnode = (node *)malloc(sizeof(node));
newnode->number = num;
newnode->next = NULL;
if(head == NULL)
{
head = newnode;
current = newnode;
}
else
{
current->next = newnode;
current = newnode;
}
}
void display(node *list)
{
list = head;
if(list == NULL)
{
return;
}
while(list != NULL)
{
printf("%d",list->number);
list = list -> next;
}
printf("\n");
}
int main()
{
int i,num;
node *n;
head=NULL;
while(1)
{
printf("\nList Operations\n");
printf("===============\n");
printf("1.Insert\n");
printf("2.Display\n");
printf("3.Exit\n");
printf("Enter your choice : ");
if(scanf("%d",&i)<=0)
{
printf("Enter only an Integer\n");
exit(0);
}
else
{
switch(i)
{
case 1:
printf("Enter the number to insert : ");
scanf("%d",&num);
add(num);
break;
case 2:
if(head==NULL)
{
printf("List is Empty\n");
}
else
{
printf("Element(s) in the list are : ");
}
display(n);
break;
case 3: return 0;
default: printf("Invalid option\n");
}
}
}
return 0;
}

The issue is with the value of current not persisting across function calls. Either move it outside of the function (i.e. right below the head declaration), or declare it as static.

just one change , define your current pointer outside the scope of void add
node *head,*current;
here is the correct code
struct link_list
{
int number;
struct link_list *next;
};
typedef struct link_list node;
node *head,*current;
void add(int num)
{
node *newnode;
newnode = (node *)malloc(sizeof(node));
newnode->number = num;
newnode->next = NULL;
if(head == NULL)
{
head = newnode;
current = newnode;
}
else
{
current->next = newnode;
current = newnode;
}
}

Related

Insertion at end in circular linked list not working in C

Please point out the error in the code.
The function insertatend() inserts for the first time but not again.
I'm trying to insert a node at the end of a circular linked list, but after inserting an element for the first time, it gets stuck in the while loop if we try to enter data again.
struct node {
int data;
struct node *next;
};
typedef struct node node;
node *head = NULL;
node *insertatend(node *head, int value)
{
node *temp, *p;
p = head;
temp = (node *)malloc(sizeof(node));
temp->data = value;
temp->next = head;
if (head == NULL)
{
head = temp;
}
else
{
while (p->next != head)
p = p->next;
p->next = temp;
}
return head;
}
void display(node *head)
{
node *p = head;
if (head == NULL)
{
printf("\nlinked list is empty\n");
return;
}
while (p->next != head)
{
printf("%d ", p->data);
p = p->next;
}
printf("\n");
}
int main()
{
int ch = 1, value;
while (ch)
{
printf("1.Insert 2.Display");
scanf("%d", &ch);
switch (ch)
{
case 1:
printf("enter an element:");
scanf("%d", &value);
head = insertatend(head, value);
break;
case 2:
display(head);
break;
}
}
return 0;
}
I think the mistake is here:
temp->next=head;
if(head==NULL){
head=temp;
}
When you enter your first element, head is null. So temp->next is set to NULL and head is set to temp.
When you enter your second element, it does this:
else{
while(p->next!=head)
p=p->next;
p->next=temp;}
Where p->next is null, so you will never have the situation that p->next == head and you will always be in the loop!
Edit:
So the solution aproach would be to change it to:
if(head==NULL){
head=temp;
}
temp->next=head;
Edit: second mistake in the display function: the loop doesn't print the last element. I just tested it and it is working fine.
So the complete code woud look like:
#include <stdio.h>
#include <stdlib.h>
struct node {
int data;
struct node *next;
};
typedef struct node node;
node *head = NULL;
node *insertatend(node *head, int value)
{
node *temp, *p;
p = head;
temp = (node *)malloc(sizeof(node));
temp->data = value;
if (head == NULL)
{
head = temp;
}
else
{
while (p->next != head)
p = p->next;
p->next = temp;
}
temp->next = head;
return head;
}
void display(node *head)
{
node *p = head;
if (head == NULL)
{
printf("\nlinked list is empty\n");
return;
}
do
{
printf("%d ", p->data);
p = p->next;
} while (p != head);
printf("\n");
}
int main()
{
int ch = 1, value;
while (ch)
{
printf("1.Insert 2.Display");
scanf("%d", &ch);
switch (ch)
{
case 1:
printf("enter an element:");
scanf("%d", &value);
head = insertatend(head, value);
break;
case 2:
display(head);
break;
}
}
return 0;
}
Alternate version, using tail pointer instead of head pointer, for faster appends.
#include <stdlib.h>
#include <stdio.h>
struct node {
struct node *next;
int data;
};
typedef struct node node;
node *insertatend(node *tail, int value)
{
node *p;
p = malloc(sizeof(node));
p->data = value;
if(tail == NULL){
p->next = p;
} else {
p->next = tail->next;
tail->next = p;
}
return p;
}
void display(node *tail)
{
node *p = tail;
if (p == NULL)
{
printf("\nlinked list is empty\n");
return;
}
do{
p = p->next;
printf("%d ", p->data);
}while(p != tail);
printf("\n");
}
int main()
{
node *tail = NULL;
int i;
for(i = 0; i < 8; i++)
tail = insertatend(tail, i);
display(tail);
return 0;
}

segmenation fault error in my linkedList -C

I put together a few pieces of code to make a linked list that adds to head(Has a special function) and in the middle(also special function).
my problem is, i need to provide the program with numbers and insert them as nodes in my LINKEDLIST. However, my display function(to display the tree of nodes) gives back segmentation fault and so does just taking values in without any display function.
I'm fairly new to malloc so i suspect the problem is there?
Thanks
#include<stdio.h>
#include<stdlib.h>
/*LINKEDLIST STRUCT*/
struct node {
int data;
struct node *next;
};
/*Inserting head-Node*/
struct node *insert_head(struct node *head, int number)
{
struct node *temp;
temp = malloc(sizeof(struct node));
if(temp == NULL)
{
printf("Not enough memory\n");
exit(1);
}
temp->data = number;
temp->next = head;
head = temp;
return head;
}
/*Inserting inside a list*/
void after_me(struct node *me, int number)
{
struct node *temp;
temp = malloc(sizeof(struct node));
if(temp == NULL)
{
printf("Not enough memory\n");
exit(1);
}
temp->data = number;
temp->next = me->next;
me->next = temp;
}
/*PRINTING LIST*/
void display(struct node *head)
{
struct node *moving_ptr = head;
while(moving_ptr != NULL)
{
printf("%d-->",moving_ptr->data);
moving_ptr = moving_ptr->next;
}
}
int main()
{
int index;
struct node *head;
struct node *previous_node;
scanf("%d", &index);
while(index > 0)
{
/*allocating in List */
if(head == NULL)
head = insert_head(head,index);
else
if((head != NULL) && (index <= (head->data)))
{
struct node *temp;
head->next = temp;
temp->next = head;/*TRY INSERT HEAD FUNC.*/
}
else
if((head != NULL) && (index > (head->data)))
{
previous_node->data = index-1;
after_me(previous_node,index);
}
scanf("%d", &index);
}
display(head);
}
I suggest as follows.
#include <stdio.h>
#include <stdlib.h>
struct node {
int data;
struct node *next;
};
//aggregated into one place
struct node *new_node(int number){
struct node *temp;
if(NULL == (temp = malloc(sizeof(*temp)))){
printf("\nNot enough memory\n");
exit(1);
}
temp->data = number;
temp->next = NULL;
return temp;
}
struct node *insert_head(struct node *head, int number) {
struct node *temp = new_node(number);
temp->next = head;
return temp;
}
void after_me(struct node *me, int number){
struct node *temp = new_node(number);
temp->next = me->next;
me->next = temp;
}
void display(struct node *head){
struct node *moving_ptr = head;
while(moving_ptr != NULL){
printf("%d", moving_ptr->data);
if(moving_ptr = moving_ptr->next)
printf("-->");
}
putchar('\n');
}
struct node *insert(struct node *me, int number){
if(me){
if(number <= me->data){
me = insert_head(me, number);
} else {
me->next = insert(me->next, number);
}
} else {
me = new_node(number);
}
return me;
}
void release(struct node *list){//Of course, you will be able to replace a simple loop(e.g while-loop).
if(list){
release(list->next);
free(list);
}
}
int main(void){
struct node *head = NULL;
int index;
while(1==scanf("%d", &index) && index > 0){
head = insert(head, index);
}
display(head);
release(head);
return 0;
}

AddNew Function using Linked List In C

Question: Create a linked list containing values in the ascending values. Then write functions addNew() which will accept a value from the user and then call addBegin() and addafterValue() functions to add the input value in the appropriate place
e.g. consider the list is like this:
12,15,20,26 then if the user enters values 8, 16 & 30 the list will look like this: 8,12,15,16,20,26,30.
My program:
#include<stdio.h>
typedef struct node
{
int data;
struct node *next;
}NODE;
NODE *start=NULL;
void append()
{
NODE *temp,*ptr;
temp=(NODE *)malloc(sizeof(NODE));
printf("Enter data:");
scanf("%d",&temp->data);
temp->next=NULL;
if(start==NULL)
start=temp;
else
{
ptr=start;
while(ptr->next!=NULL)
ptr=ptr->next;
ptr->next=temp;
}
}
void display()
{
NODE *ptr=start;
while(ptr!=NULL)
{
printf("%d\n",ptr->data);
ptr=ptr->next;
}
}
void addBegin(int val)
{
NODE *temp;
temp=(NODE *)malloc(sizeof(NODE));
temp->data=val;
temp->next=start;
start=temp;
}
unsigned int addAfterValue(int val,NODE *ptr)
{
NODE *temp;
temp=(NODE *)malloc(sizeof(NODE));
temp->data=val;
temp->next=ptr->next;
return temp;
}
void addNew()
{
int val;
unsigned int loc;
NODE *ptr=start;
printf("Enter value to add:");
scanf("%d",&val);
if(val<ptr->data) {
addBegin(val);
ptr=NULL;
}
while(ptr!=NULL) {
if(ptr->next!=NULL)
{
if(val<ptr->next->data)
{
addAfterValue(val,ptr);
ptr->next=loc;
ptr=NULL;
}
else
{
ptr=ptr->next;
}
}
if(ptr->next==NULL)
{
loc=addAfterValue(val,ptr);
ptr=NULL;
}
}
}
int main()
{
int ans;
do
{
printf("Enter [1]To append\n[2]To add new node\n[3]To display\n[0]To exit\n");
printf("Enter your choice:");
scanf("%d",&ans);
switch(ans)
{
case 1:
append();
break;
case 2:
addNew();
break;
case 3:
display();
break;
case 0:
break;
default:
printf("Wrong Input.Try again.");
}
}while(ans);
}
My doubt: The addBegin() function works perfectly. I think there's something wrong with addafterValue(). Can anyone help me by finding out my mistake?
Instead of passing the current pointer address.
Use the previous node pointer and assign to its next node.
void addAfterValue(int val,NODE *ptr)
{
NODE *temp = (NODE *)malloc(sizeof(NODE));
temp->data=val;
temp->next=ptr->next;
ptr->next = temp;
}
Change the addNew function
void addNew()
{
int val;
NODE *ptr=start;
NODE *prev= NULL;
printf("Enter value to add:");
scanf("%d",&val);
if( ptr == NULL || val < ptr->data)
{
addBegin(val);
return;
}
else
{
prev = ptr;
ptr=ptr->next;
}
while( ptr != NULL)
{
if( val <= ptr->data)
{
addAfterValue(val,prev);
return;
}
else
{
prev = ptr;
ptr=ptr->next;
}
}
/* Control comes here if the entire list is scanned.... Now append it to the end using prev pointer, as the new node is greater than all of the existing nodes */
}

Linked list (sorted insertion)

this program creates a sorted list and then inserts an element such that the list still remains sorted. I think the logic is ok..but the program doesn't print the new list formed.Here is the code. what is wrong?
#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
struct list {
int number;
struct list *next;
};
typedef struct list node;
void create(node *);
void print(node *);
void sortedInsert(node **);
main() {
int user_response;
node *head;
head = (node *)malloc(sizeof(node));
create(head);
printf("Look at your creation!! A linked list!!1 heheheh...........\n");
print(head);
printf("Do you want to experience some \"sort\" of thrill?\n1 for yes..\n");
scanf("%d",&user_response);
if(user_response == 1) {
sortedInsert(&head);
printf("Look at the marvel of linked list...\n");
print(head);
}
else {
printf("Ha\n tired fellow,lack of ambition!!!\n");
exit(0);
}
return 0;
}
void create(node *head) {
printf("Enter a number,-999 to stop\n");
scanf("%d",&head->number);
if(head->number == -999) {
head->next = NULL;
}
else {
head->next = (node *)malloc(sizeof(node));
create(head->next);
}
}
void print(node *head) {
if(head->next != NULL) {
printf("%d-->",head->number);
print(head->next);
}
else {
printf("%d",head->number);
}
}
void sortedInsert(node **headRef) {
node *new_node;
node *prev_ptr = *headRef;
node *dummy_ptr = *headRef;
int key;
printf("Which value do you wanna insert\n");
scanf("%d",&key);
new_node = (node *)malloc(sizeof(node));
new_node->number = key;
while((*headRef)->next != NULL) {
if((*headRef)->number >= key) {
prev_ptr->next = new_node;
new_node->next = *headRef;
*headRef = dummy_ptr;
}
else {
prev_ptr = *headRef;
*headRef = (*headRef)->next;
}
}

Linked List not working for insertion

I have written a linked list code to insert a element in the node. But the problem is when i want to insert first element using function, the output is coming empty. But when i insert first element inside the main function (see comment line), it gives the correct output. How to solve it ?
Here is my C code:
#include<stdio.h>
#include<stdlib.h>
typedef struct node{
int val;
struct node *next;
}node;
void print(node *head){
if(tem == NULL){
printf("List is Empty\n");
return;
}
node *tem= head;
while(tem != NULL){
printf("%d ", tem->val);
tem= tem->next;
}
}
void insert(node *head, int val){
if(head == NULL){
node *tem= malloc(sizeof(node*));
tem->val= val;
tem->next= NULL;
head= tem;
return;
}
node *tem= head;
while(tem->next != NULL){
tem= tem->next;
}
tem->next= malloc(sizeof(node*));
tem->next->val = val;
tem->next->next= NULL;
}
int main()
{
node *head= NULL;
/*
head = malloc(sizeof(node*));
head->val= 5;
head->next= NULL;
*/
insert(head, 15);
print(head);
return 0;
}
Thanks
Try sending the address of the head instead of head as shown below:
insert(&head, 15);
void insert(node **head, int val){
if(*head == NULL){
node *tem= malloc(sizeof(node*));
tem->val= val;
tem->next= NULL;
*head= tem;
return;
}
This is because when you are sending the head, any changes made will be local to that function (insert in this case) and won't be reflected outside that function. Hence, you have to send the address of head (&head) so that changes made to head are reflected outside the function as well. Cheers
Try this completely implemented singly linked list:
#include <stdio.h>
struct node{
int data;
struct node *next;
};
struct node *head=NULL;
void insert(int data, int position)
{
struct node *newNode=malloc(sizeof(struct node));
newNode->data=data;
if(position<1)
{
printf("Invalid Insertion Position \n");
return;
}
if(head==NULL && position==1)
{
newNode->next=NULL;
head=newNode;
}
else if(head==NULL && position!=1)
{
printf("Invalid Insertion Position \n");
}
else if(position==1)
{
newNode->next=head;
head=newNode;
}
else
{
int i=0;
struct node *temp=head;
while(temp->next!=NULL && i<position-2)
{
i++;
temp=temp->next;
}
if(i<position-2)
{
printf("Invalid Insertion Position \n");
}
else
{
newNode->next=temp->next;
temp->next=newNode;
}
}
}
void delete(int position)
{
int i=0;
if(position<1)
{
printf("Invalid Position of Deletion \n");
return;
}
if(head==NULL)
{
return;
}
if(position==1)
{
head=head->next;
}
else
{
struct node *temp=head;
while(temp->next->next!=NULL && i<position-2)
{
i++;
temp=temp->next;
}
if(i<position-2)
{
printf("Invalid Position of Deletion \n");
return;
}
else
{
temp->next=temp->next->next;
}
}
}
void printlist()
{
if(head==NULL)
{
printf("Empty List!! \n");
return;
}
struct node *temp=head;
while(temp!=NULL)
{
printf("%d",temp->data);
printf("\t");
temp=temp->next;
}
printf("\n");
}
int main()
{
int t;
printf("Enter number of Test Cases: \t");
scanf("%d", &t);
printf("\nEnter Queries in this format: \n");
printf("For Insertion: \t I data position \n");
printf("\tEx:\t I 25 5 \n");
printf("For Deletion: \t D position \n");
printf("\tEx:\t D 2 \n\n");
while(t--)
{
char c;
int a,b;
printf("Enter query: \t");
scanf("%c", &c);
scanf("%c", &c);
if(c=='I')
{
scanf("%d %d", &a,&b);
insert(a,b);
}
else if(c=='D')
{
scanf("%d", &a);
delete(a);
}
printlist();
}
}

Resources