why this linked list code in c malfunction? - c

I have written this code in c to implement linked list. while the semantic and syntax are fine, it does not work as it should. For example, when I insert 1 into the list and then print the linked list, it shows that the list is empty.
#include<stdio.h>
#include<stdlib.h>
struct node {
int info;
struct node *next;
}; typedef struct node Node;
void addNode(Node *head, int x)
{
Node *temp;
temp=malloc(sizeof(temp));
temp->info=x;
if (head==NULL)//if this is the first node in the list
{
head=temp;
temp->next=NULL;
}
else //if not, add it as the head
{
temp->next=head;
head=temp;
}
}
void appendNode(Node *head, int x)
{
Node *rear =head;
Node *temp= malloc(sizeof(temp));
temp->info=x;
temp->next=NULL;
while (rear->next!=NULL)
rear=rear->next;
rear->next=temp;
rear=temp;
}
void insertNodeafter(Node *head, int location, int x)
{
int i;
Node *before, *after = head;
Node *temp= malloc(sizeof(temp));
temp->info=x;
for (i=0;i<location;i++)
before=before->next;
after=before->next;
temp->next=after;
before->next=temp;
}
void insert(Node *head, int x)
{
int c=0;
Node *temp;
temp=head;
if(temp==NULL)
{
addNode(temp,x);
}
else
{
while(temp!=NULL)
{
if(temp->info<x)
c++;
temp=temp->next;
}
if(c==0)
addNode(temp,x);
else if(c<listSize())
insertNodeafter(temp,x,++c);
else
appendNode(temp,x);
}
}
int listSize()
{
Node *head, *n;
int c=0;
n=head;
while(n!=NULL)
{
n=n->next;
c++;
}
return c;
}
void DisplayLinkedList(Node* head)
{
Node *rear=NULL;
if (head==NULL)
printf("list is empty!\n");
else
{
rear=head;
while (rear!=NULL)
printf("%d |---> ", rear->info);
rear=rear->next;
}
}
int getNextNode(Node *head)
{
if (head == NULL)
return -1;
else
return head->next->info;
}
Node* deleteNode(Node *head, int x)
{
Node *temp;
if (head == NULL)
return NULL;
else
{
if (head->info==x)
{
temp = head->next;
free(head);
head=temp;
return head;
}
else
{
deleteNode(head->next,x);
return head;
}
}
}
void main()
{
int i=0;
Node *myNode;
insert(myNode,1);
DisplayLinkedList(myNode);
}

Because you are using Node* variable instead of using Node** variable in function parameter. Since you are using Node* so changes done in variable head is local to that function. If you want to reflect these changes even after function call(which you obviously wants to) then use Node** and use it accordingly in your code.

As the previous poster has mentioned, it is best to use Node** variable to reflect changes after a function call. If you wanted to use Node*, you'd have to return Node* back to main to print from it.
I pared your code down to add the 1, using AddNode, insert and DisplayLinkedList and it is now displaying correctly with the code below.
You should also set Node* to NULL in main to initialize the empty linked list. Check your DisplayLinkedList function - you're missing curly brackets in the while loop. It was only reading the printf line and not traversing the list, leading to an infinite loop.
Best practice is to debug and test as you are creating this program.
#include<stdio.h>
#include<stdlib.h>
#include "stack.h"
void main()
{
int i=0;
Node *myNode;
myNode = NULL;
insert(&myNode,1);
DisplayLinkedList(myNode);
}
void addNode(Node **head, int x)
{
Node *temp;
temp=malloc(sizeof(temp));
temp->info=x;
if (*head==NULL)//if this is the first node in the list
{
*head=temp;
temp->next = NULL;
}
else //if not, add it as the head
{
temp->next=*head;
*head=temp;
}
}
void insert(Node **head, int x)
{
int c=0;
Node *temp;
temp=*head;
if(temp==NULL)
{
addNode(head ,x);
}
}
void DisplayLinkedList(Node* head)
{
Node *rear=NULL;
if (head==NULL)
printf("list is empty!\n");
else
{
rear=head;
while (rear!=NULL)
{
printf("%d |---> ", rear->info);
rear=rear->next;
}
}
}

Related

Linked list in c returns negative number instead of adding node

Can someone explain to me why this code returns a random negative number instead of adding the node as it should? If the call to addnode is removed the main function works as it should so the problem lies with the addnode function. I don't think it's malloc that has the problem and I can't for the life of me figure out what is. Please help, I'm an amateur at c and I have a vague understanding of how pointers work so I guess something's wrong with my pointers. Here's the full code :
#include <stdio.h>
#include <stdlib.h>
struct node
{
int data;
struct node *next;
};
int addNode(struct node **head, int value);
void printList(struct node **head);
int main()
{
int value;
struct node *head;
head=NULL;
//int isempty(struct node *head);
for(int i=0;i<10;i++)
{
printf("\nInsert node value :");
scanf("%d",&value);
addNode(&head,value);
}
printList(&head);
return 0;
}
int addNode(struct node **head,int value)
{
struct node *newnode;
newnode=(struct node *) malloc(sizeof(struct node));
//if(newnode==NULL)
if(!newnode)
{
printf("Memory allocation error \n");
exit(0);
}
if(*head=NULL)
{
newnode->data=value;
newnode->next=NULL;
*head=newnode;
return 1;
}
else
{
struct node *current;
*current = **head;
while(current != NULL)
{
if(value<=(current->data)){
//περίπτωση 1ου κόμβου σε μη κενή λίστα
if(current==*head){
newnode->data=value;
newnode->next=*head;
*head=newnode;
return 1;
}
//περίπτωση ενδιάμεσου κόμβου
newnode->data=value;
return 1;
}
current = current->next;
}
}
}
/*int isempty(struct node *head){
return (head==NULL);
}*/
void printList(struct node **head) {
struct node *ptr = *head;
printf("\n[ ");
//start from the beginning
while(ptr != NULL) {
printf("(%d) ",ptr->data);
ptr = ptr->next;
}
printf(" ]");
return;
}
Well for starters you are having an assignment instead of a comparison in addNode
if(*head=NULL) should be if(*head==NULL)
Other than that, I think you are trying to maintain the elements in a sorted manner? But in any case you are manipulating pointers a bit more than you need to.

unable to insert in a linked list

i am trying to insert an element in the given linked list but when i want to print it its showing infinite loop.In insert() call i am passing the address of the pointer whereas in display i am only passing the address stored in the pointer. help me plz
#include<stdio.h>
struct node{
int item;
node *ptr;
};
int insert(node **head, int data, int position)
{
int count=1;
node *temp=malloc(sizeof(struct node));
temp->item=data;
temp->ptr=NULL;
node *p,*q;
p=*head;
if(*head==NULL)
{
*head=temp;
}
if(position==1)
{
temp->item=*head;
*head=temp;
}
else{
while(p!=NULL&&count<position)
{
count++;
q=p;
p=p->ptr;
}
q->ptr=temp;
temp->ptr=p;
}
}
void display(node *temp)
{
while(temp!=NULL)
{
printf("the data is %d",temp->item);
temp=temp->ptr;
}
}
void main()
{
node *head=malloc(sizeof(struct node));
insert(&head,29,1);
display(head);
}
Its a C Program please categorize properly.
No use of any C++ modules in your code.
Going with C implementation -
I think the double pointer is not required in a simple insert into a linked list.
You can do is -
void insert(node *head, int data){
node *temp= malloc(sizeof(struct node));
temp->item = data;
temp->ptr= NULL;
if(head==NULL){ //empty list
head=temp;
}
else {
while(head->ptr!=NULL){ //traverse till end
head=head->ptr;
}
head->ptr=temp;
}
}
And from main function call as insert(head,value);

I want to swap the linkedlist terms pairwise, my code is giving me Segmentation Fault

I want to swap the linkedlist terms pairwise.
Here is my code. It is giving me Segmentation Fault-core dumped
#include <stdio.h>
#include <stdlib.h>
struct node
{
int data;
struct node *next;
}*head;
void insert(struct node *n)
{
int num;
printf("Enter a number : ");
scanf("%d",&num);
struct node *temp;
temp=(struct node *)malloc(sizeof(struct node));
temp->data=num;
if(n==NULL)
{
head=temp;
head->next=NULL;
}
else
{
temp->next=head;
head=temp;
}
}
int main()
{
struct node *n;
head=NULL;
n=head;
int i;
for(i=0;i<6;i++)
{
insert(n);
n=head;
}
display(n);
pairswap(n);
display(n);
}
void display(struct node *n)
{
struct node *temp;
temp=n;
while(temp!=NULL)
{
printf("%d ",temp->data);
temp=temp->next;
}
}
void pairswap(struct node *n)
{
struct node *temp,*temp1,*temp2;
temp=n;
temp1=temp->next;
while(temp!=NULL)
{
int tempnum;
tempnum=temp->data;
temp->data=temp1->data;
temp1->data=tempnum;
if(temp==n)
{
head=temp;
head->next=temp1;
}
else
{
temp2->next=temp;
temp2->next->next=temp1;
}
temp2=temp1;
temp=(temp->next)->next;
temp1=temp->next;
}
n=head;
}
Please learn about the debuggers.
Somewhere at the end of the list the value of
(temp->next)->next
is NULL, which you are putting it in variable temp.
Before making this assignment temp1=temp->next, you need to check if temp is NULL and take proper action.
The problem is pairswap function. In the while loop you are using the condition:
while(temp!=NULL)
and inside the loop you are assigning:
temp=(temp->next)->next
which will get crashed on the second last node since you are trying to dereference NULL pointer.
Use the following condition:
while((temp->next)->next!=NULL)
or
while (temp1->next != NULL)

Inserting error in an hashtable of queues as linked list?

I've implemented the following code for queues as a linked list. Now I'm trying to get an hashtable as an array of queues as a linked list. It works fine until I do insertion after deletion.
What is being done is a queue is implemented as linked list. So when I want to remove, I delete the head element and for insert I use tail.
To do an hashtable I maintain another linked list of keys in the order in which they were inserted. Deletion starts with first removing this key and going to that individual linked list and removing the head and updating the head.
#include<stdio.h>
#include<stdlib.h>
struct Node{
int value;
struct Node *next;
struct Node* head;
struct Node* tail;
};
struct Node* lruhashtable[10];
struct Node* trackHead;
struct Node* trackTail;
void insert(int page)
{
if(trackHead==NULL)
{
trackHead=malloc(sizeof(struct Node));
trackHead->value=(page-1)%10;
trackHead->next=NULL;
trackTail=trackHead;
}
else
{
struct Node* temp=malloc(sizeof(struct Node));
temp->value=(page-1)%10;
temp->next=NULL;
trackTail->next=temp;
trackTail=temp;
}
}
void hashEntry(int page)
{
struct Node** iter;
iter=&lruhashtable[(page-1)%10];
for(;*iter;iter=&(*iter)->next);
*iter = malloc(sizeof **iter );
(*iter)->value = page;
(*iter)->next = NULL;
if((*iter)->head==NULL)
{
(*iter)->head=*iter;
(*iter)->tail= (*iter)->head;
}
else
{
(*iter)->tail->next=*iter;
(*iter)->tail=*iter;
}
insert(page);
}
void deleteInHashEntry()
{
int pageToDelete=delete();
struct Node** iter;
iter=&lruhashtable[pageToDelete];
if((*iter)->head!=NULL)
{
struct Node* curr=(*iter)->head;
(*iter)=curr->next;
if((*iter)!=NULL)
(*iter)->head=*iter;
free(curr);
}
else
{
(*iter)->tail=NULL;
}
}
void print()
{
int i;
struct Node **iter;
for(i=0;i<10;i++)
{
iter=&lruhashtable[i];
for(;*iter;iter=&(*iter)->next)
{
printf("%d%s%d\n",(*iter)->value,"--",i);
}
}
}
int delete()
{
int page=-1;
if(trackHead!=NULL)
{
struct Node*current=trackHead;
page=current->value;
trackHead=current->next;
free(current);
}
else
{
trackTail=NULL;
}
return page;
}
void printTrack()
{
struct Node* temp=trackHead;
while(temp!=NULL)
{
printf("%d",temp->value);
printf("\n");
temp=temp->next;
}
}
int main()
{
hashEntry(1);
hashEntry(11);
hashEntry(2);
hashEntry(3);
hashEntry(22);
hashEntry(4);
hashEntry(33);
print();
printTrack();
deleteInHashEntry();
print();
printTrack();
deleteInHashEntry();
print();
printTrack();
deleteInHashEntry();
print();
printTrack();
hashEntry(1);
hashEntry(11);
hashEntry(22);
deleteInHashEntry();
deleteInHashEntry();
deleteInHashEntry();
deleteInHashEntry();
deleteInHashEntry();
deleteInHashEntry();
deleteInHashEntry();
return 0;
}
GDB to the rescue, thought I think I should have caught it much before,in the function hashEntry if((*iter)->head==NULL) this statement is wrong as everytime this will execute after malloc. Added a STATUS variable to do this check before malloc statement and change if condition to if status. Hopefully this is the only bug.

What is wrong with my code for singly linked list?

I'm working on a singly linked list in C. This is what I've written so far.
C program
#include<stdio.h>
#include<stdlib.h>
struct Node{
int value;
struct Node *next;
};
struct Node* init()
{
struct Node* head=NULL;
head=malloc(sizeof(struct Node));
head->value=-1;
return head;
}
int length(struct Node* head)
{
struct Node* current=head;
int length=0;
while(current!=NULL)
{
length++;
current=current->next;
}
return length;
}
void print(struct Node* head)
{
int i=0;
int len=length(head);
for(i=0;i<len;i++)
{
printf("%d%d",i,head[i].value);
printf("\n");
}
}
struct Node* insert(int data,struct Node* head)
{
struct Node* current=NULL;
if(length(head) > 0)
{
int val=head->value;
if (val==-1)
{
head->value=data;
head->next=NULL;
}
else
{
current=malloc(sizeof(struct Node));
current->value=data;
current->next=head;
head=current;
}
}
else
{
printf("List is empty");
}
return head;
}
int main()
{
/* printf("Hello"); */
struct Node *head=init();
head=insert(20,head);
head=insert(30,head);
head=insert(40,head);
print(head);
printf("%d",length(head));
return 0;
}
The output values I get are:
Index Value
0 40
1 0
2 0
and for length is 3. I'm not able to grasp what I'm doing wrong here in pointer manipulation.
One obvious problem is not setting next to NULL on init - that would fail when checking length on the empty list
But your real problem is the print function
You can't use:
head[i].value
That notation is only valid for arrays, you need to use next to find each member
The Init function should set Next to NULL
struct Node* init()
{
struct Node* head=NULL;
head=malloc(sizeof(struct Node));
head->value=-1;
head->next=NULL;
return head;
}
otherwise the first call to length return an undefined result ( or GPF ).
Here:
for (i = 0; i < len; i++)
{
printf("%d%d", i, head[i].value);
printf("\n");
}
You need to advance from one node to another with head = head->next in the same manner as you do it in length(). head[i] won't do it.
It's unclear why your init() and insert() are so unnecessarily complicated and I don't even want to try to guess why. I want to suggest a better insert() and no init():
struct Node* insert(int data, struct Node* head)
{
struct Node* current;
current = malloc(sizeof(struct Node));
current->value = data;
current->next = head;
return current;
}
And then you do this:
int main(void)
{
struct Node *head = NULL;
head = insert(20, head);
head = insert(30, head);
head = insert(40, head);
print(head);
printf("%d", length(head));
return 0;
}
The notation head[i].value is only valid for arrays but not for linked lists. Arrays and linked lists are completely different, allocation of memory towards arrays is premeditated where as for linked lists it's dynamic. That is the reason why we use pointers for linked lists.
In init() you didn't assign null which causes the loop to run infinite times when you call length() for first time.
I am posting the modified code of print function:
void print(struct Node* head)
{
int i=0;
int len=0;
struct Node* current=head;
for(i=0;i<len;i++)
{
printf("%d %d",i,current->value);
print("\n");
current=current->next;
}
}

Resources