Display circular list endless loop - c

I have two functions:
void display(struct node *start) {
struct node *ptr;
ptr = start;
while (ptr -> next != start) {
printf("\t %d", ptr -> data);
ptr = ptr -> next;
}
printf("\t %d", ptr -> data);
}
struct node *insert_beg(struct node *start) {
struct node *new_node;
new_node = (struct node *)malloc(sizeof(struct node));
printf("\n Enter data : ");
scanf("%d", &new_node -> data);
new_node -> next = start;
start = new_node;
return start;
}
After using insert_beg(start) and trying to display this list using display(start), I have an endless loop.
Thanks for your support.

You are not creating a circular list here.
For creating circular list you have to handle one more case when there is no element in the list i.e. start is NULL (list is empty).
Make following edit to it after the scanf part of insert_beg() function :
if(start == NULL){ // this is the required condition to be added
start = new_node;
start->next = start;
}
else{
// this code for adding element is to be performed only when list is not empty
struct node *tmp = start->next;
start->next = new_node;
new_node->next = temp;
}
I hope it will solve your problem !!

Because you didn't provided a complete example how do you build the circular list, let me assume that you are using the insert_beg function wrong.
If I use your function like follows, there is no endless loop:
int main() {
struct node* start;
start = (struct node*)malloc(sizeof(struct node));
start->data = 1;
start->next = start; /* initializing the next pointer to itself */
start->next = insert_beg(start->next);
start->next = insert_beg(start->next);
start->next = insert_beg(start->next);
display(start);
return 0;
}
I see an issue in your insert_beg too:
start = new_node;
If you intend to overwrite where the start points to, then you have to change your function signature to the following:
struct node *insert_beg(struct node **start);
Then inside the function you can do the following:
new_node->next = *start; /* access the pointer pointed by start */
*start = new_node; /* overwrite where the pointer pointed by start points to*/
return *start; /* losts its meaning */
The modifications above let you use your insert_beg function as follows:
insert_beg(&start->next);
insert_beg(&start->next);
insert_beg(&start->next);

Related

Why does a linked list with a double pointer cause an error?

I'm asking you a question because the assignment I was doing didn't work out.
The structure is a common link list, declaring the head pointer in the main and passing the address value of the head pointer as a parameter to the function.
The global variable top is used to determine where the current data is located.
The code currently below will detect only errors when executed.
Structure:
struct ListNode{
int data;
struct ListNode* link;
};
int top = 0;
code:
void DisplayList(ListNode** head){
if(*head == NULL){
printf("List = Empty\n");
}
else{
printf("List = ");
for(;(*head) != NULL; *head = (*head)->link){
printf("%d ",(*head)->data);
}
}
printf("\n");
}
void AddList(ListNode** head){
ListNode* temp = (ListNode*)malloc(sizeof(ListNode));
int num;
printf("Data register) ");
scanf("%d",&num);
temp->data = num;
temp->link = NULL;
top++;
if(*head == NULL){
*head = temp;
}
else{
for(;(*head)->link != NULL; *head = (*head)->link){}
(*head)->link = temp;
}
DisplayList(head);
}
the expected result:
Data register) 10
List = 10
Data register) 20
List = 10 20
Data register) 30
List = 10 20 30
You shouldn't modify *head in the loops. You need to use a local variable to step through the list, otherwise you're changing the caller's variable to point to the end of the list.
void DisplayList(ListNode** head){
if(*head == NULL){
printf("List = Empty\n");
}
else{
printf("List = ");
for(ListNode *step = *head;step != NULL; step = step->link){
printf("%d ",step->data);
}
}
printf("\n");
}
void AddList(ListNode** head){
ListNode* temp = (ListNode*)malloc(sizeof(ListNode));
int num;
printf("Data register) ");
scanf("%d",&num);
temp->data = num;
temp->link = NULL;
top++;
if(*head == NULL){
*head = temp;
}
else{
ListNode *step = *head;
for(;step->link != NULL; step = step->link){}
step->link = temp;
}
DisplayList(head);
}
Your error is in how you traverse the list:
for(; (*head)->link != NULL; *head = (*head)->link) {}
At the beginning, *head is the head of the list from the calling function. By assigning to it, you overwrite it continuously, until it becomes null.
Instead, you should assign to head: It holds the address of the head node in the calling function at first and the address of the link pointer of the previous node in subsequent iterations:
for(; (*head)->link != NULL; head = &(*head)->link) {}
After this loop, head holds the address of the pointer where the new node should be stored. Assign the new node to that pointer directly:
*head = temp;
This will update the head pointer of the calling function when the list was empty and the link member of the previous node otherwise. You don't have to treat the case where the list is empty specially.
The insertion function might now look like this:
void AddList(ListNode** head, int num)
{
ListNode* temp = malloc(sizeof(ListNode));
temp->data = num;
temp->link = NULL;
while (*head) head = &(*head)->link);
*head = temp;
}
(In my opinion, reading the input and printing the list shoudl not be part of te insertion function.)
Regarding your printing function: Seeing a function like that:
void DisplayList(ListNode** head)
raises a red flag: Passing a pointer to node pointer signals that you want to modify the list (and you inadvertently do that), but printing the list only inspects it. Change the signature to
void DisplayList(const ListNode* head)
then use head instead of (*head) in the function. (Rule of thumb: If you never use *head = ... somewhere in the list, you don't need a pointer to node pointer.)

Segmentation Fault when creating a queued list of objects

Task is to create objects in the main and have them passed to other functions, which will create a list of type queue. That's the algorithm I'm using:
Write a function of type Node * which will return a pointer to the last Node of the list
To insert a Node at the end of the list, it's required to get a pointer to the last Node
Create a new Node
Assign the newly created Node the object that's been passed to the function
Make next from the last Node point the new one
Here's the code:
typedef struct Node{
int val;
char str[30];
struct Node *next;
}Node;
void printList(const Node * head);
void queue(Node *head, Node *object);
Node *getLast(Node *head);
int main(void){
Node *head = NULL;
Node *object = (Node *)malloc(sizeof(Node));
int c = 0;
while(1){
printf("This int will be stored in Node %d.\n", ++c);
scanf("%d", &object->val);
if(!object->val){
puts("You've decided to stop adding Nodes.");
break;
}
fflush(stdin);
printf("This string will be stored in Node %d.\n", c);
fgets(object->str, 30, stdin);
if(!(strcmp(object->str, "\n\0"))){
puts("You've decided to stop adding Nodes.");
break;
}
queue(head, object);
}
printList(head);
return 0;
}
void printList(const Node *head){
if(head == NULL){
puts("No list exists.");
exit(1);
}
while(1){
printf("|||Int: %d|||String: %s|||\n", head->val, head->str);
if(head->next){
head = head->next;
}
else{
break;
}
}
}
Node *getLast(Node *head){
if(head == NULL){
return NULL;
}
while(head->next){
head = head ->next;
}
return head;
}
void queue(Node *head, Node *object){
Node *last = getLast(head);
Node *tmp = (Node *)malloc(sizeof(Node));
*tmp = *object;
tmp -> next = NULL;
last -> next = tmp;
}
Maybe the problem is in having getLast return NULL. But then again, this exact same thing worked when I created a list consisting only of int.
As pointed out in the comment section, last->next = tmp fails for first call to queue() as getLast() returns NULL. A correct solution would be like this:
void queue(Node **head, Node *object){
Node *last = getLast(*head);
Node *tmp = (Node *)malloc(sizeof(Node));
*tmp = *object;
tmp -> next = NULL;
if (last != NULL)
last -> next = tmp;
else
*head = tmp;
}
and call queue(&head, object) from main().

LinkedList with unwanted zeros

Ive looked around and I'm not sure if it has been posted or not, but I am trying to create two linked lists in C. When they are supposed to be 'empty' there are zeros. I am not sure where these zeros are coming from and its confusing the hell out of me.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct node
{
int price;
int bookNumber;
struct node * next;
};
void addNode(struct node* pHead, int pPrice, int pBookNumber);
void displayList(struct node* pHead);
void removeNode(struct node* pHead, int pBookNumber);
int main()
{
struct node* head1;
head1 = (struct node*)malloc(sizeof(struct node));
head1 -> next = NULL;
addNode(head1, 10, 1234);
addNode(head1, 35, 9876);
displayList(head1);
printf("\n");
struct node* head2;
head2 = (struct node*)malloc(sizeof(struct node));
head2 -> next = NULL;
// addNode(head2,13, 8888);
displayList(head2);
}
void addNode(struct node* pHead, int pPrice, int pBookNumber)
{
struct node* newNode;
struct node* ptr;
newNode = (struct node*)malloc(sizeof(struct node));
newNode -> price = pPrice;
newNode -> bookNumber = pBookNumber;
newNode -> next = NULL;
ptr = pHead;
if(pHead -> next == NULL)
{
pHead -> next = newNode;
newNode -> next = NULL;
}
else
{
while((ptr -> next != NULL))
{
ptr = ptr -> next;
}
ptr -> next = newNode;
newNode -> next = NULL;
}
}
void removeNode(struct node* pHead,int pBookNumber)
{
struct node *current, *prev;
current = pHead;
/*searching list for the desired data*/
while((current -> bookNumber != pBookNumber))
{
prev = current;
current = current -> next;
}
/*fixing links between nodes*/
prev -> next = current -> next;
/*freeing memory*/
free(current);
/*removing from end of list*/
if((current -> next = NULL))
{
prev -> next = NULL;
/*freeing memory*/
free(current);
}
}
void displayList(struct node* pHead)
{
while(pHead != NULL)
{
printf("$%d, book# %d -> ", pHead -> price, pHead -> bookNumber);
pHead = pHead -> next;
}
printf("NULL");
}
I added two entries to the first list and didn't add anything to the second list...Here is the output:
$0, book# 0 -> $10, book# 1234 -> $35, book# 9876 -> NULL
$0, book# 0 -> NULL
Process returned 0 (0x0) execution time : 0.001 s
Press ENTER to continue.
the first noticeable problem is that you appear to have a dummy node
in the beginning of the list
struct node* head1;
head1 = (struct node*)malloc(sizeof(struct node));
head1 -> next = NULL;
but you start printing from head not from head->next
ie including dummy node.
head1 and head2 are uninitialized nodes which you allocate in main. You then add two nodes to head1 and none to head2. You then print the lists from head1 and head2. So they start by printing those uninitialized nodes.
You are starting your print loop from the head, and at the very beginning you allocate the memory for your head1 node. This causes it to print the price and number of the node with unassigned price and book number.
This can be solved by passing a pointer to a pointer (struct node **pHead) into your addNode function and adding a check if the head node is NULL.
newNode -> next = NULL;
ptr = pHead;
if(pHead -> next == NULL)
{
pHead -> next = newNode;
newNode -> next = NULL;
}
else
{
while((ptr -> next != NULL))
{
ptr = ptr -> next;
}
ptr -> next = newNode;
newNode -> next = NULL;
}
This code has another issue here. You are setting the next pointer of newNode to NULL at the start, and then again prior to exiting out of your if-else. This is not necessary, because you are always going to the very end of the list.
free(current);
/*removing from end of list*/
if((current -> next = NULL))
{
prev -> next = NULL;
/*freeing memory*/
free(current);
}
This code has an issue of freeing the current node, and then I assume you are attempting to check if you are at the very end of the list. However, you are using an assignment operator here. Use == for comparison, and were you to attempt removal of nodes, this would cause a segmentation fault, because you are trying to access the memory you had just freed.
Another thing worthy of mention here is that the current->next will be NULL in fact, if this is the end of the list, so this check is not even necessary and thus can be removed all together.

Linked list shows only first node element on printing

I am trying to create a linked list in order to enhance my concepts of pointers and address. I have to create linked list in following way:
(1) Read all the nodes together at once at terminal.
(2) Then show the final linked list so formed at last.
How i try to do so ?
I am reading first the size of linked list (total number of nodes to be entered). Then i read all the nodes 1 by one in do-while loop. After reading all the nodes i try to create linked list. I differentiate the case when the node is first node to be created by a count variable which will have count=0 when the node is first node after that it will be in another loop.
The output i get is as follows:
enter the size of node
4
start entering the number of elements until your size
2
3
4
5
Printing linked list
2-> //It don't print the other nodes, Just first one
hp#ubuntu:~/Desktop/pointer$
My full code to do so is :
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>
struct node
{
int freq;
struct node * next;
};
typedef struct node node;
node * tree;
void main()
{
int size, data;
int count = 0; //this count flag is to check is it's first node or not inside the do-while loop.
tree = NULL;
printf("enter the size of node\n");
scanf("%d", & size);
printf("start entering the number of elements until your size\n");
node * temp3 = tree;
node * prev;
//Problem creating area is below
do
{
scanf("%d", & data);
if (count == 0)
{
node * temp;
temp = (node * ) malloc(sizeof(node));
temp-> freq = data;
temp-> next = NULL;
prev = temp;
}
else if (count != 0)
{
node * temp;
temp = (node * ) malloc(sizeof(node));
temp-> freq = data;
temp-> next = NULL;
prev-> next = temp;
}
size--;
++count;
}
while (size > 0);
printf("Printing linked list\n");
node * temp1;
temp1 = prev;
//there may be problem here
while (temp1-> next != NULL)
{
printf("%d-> ", temp1-> freq);
temp1 = temp1-> next;
}
printf("\n");
}
Couldanyone please help me in printing the full linked list by pointing me the error with it's solution ?
Okay there is some unnecessary pointers and a few pointer mistakes being made, for ease of answering I've rewritten your code, I'll try to explain what I did here:
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>
struct node
{
int freq;
struct node * next;
};
typedef struct node node;
//only need two pointers when building a linked list, one for the top and one for the
//current node
node *tree = NULL, *curr = NULL; //init both pointers to NULL initially
int main()
{
int size, data; //dont need count, you'll see in a minute why
printf("enter the size of node\n");
scanf("%d", & size);
printf("start entering the number of elements until your size\n");
//Problem creating area is below
do
{
scanf("%d", &data);
if (tree == NULL) //just test for top node being NULL instead of using count
{
node *temp;
temp = malloc(sizeof(node));
temp->freq = data;
temp->next = NULL;
//stylistically i like using curr rather than prev, just a style choice
tree = temp; //set tree to first node
curr = tree; //make the top node the current node
}
else //don't need else if, there are only two conditions
{
node *temp = malloc(sizeof(node));
temp->freq = data;
temp->next = NULL;
curr->next = temp; //set the next node in list to the new one
curr = curr->next; //here's where you had pointer issues, move the current
//to the newly created node
}
size--;
}
while (size > 0);
printf("Printing linked list\n");
curr = tree; //reuse curr, no need to make a new pointer
//test for the current node being NULL, takes care of special case of empty list
//causing a segfault when you attempt to access a member of an invalid pointer
while (curr != NULL)
{
printf("%d->", curr->freq);
curr = curr->next; //move to next item in list
}
printf("\n");
return 0;
}
I ran a sample run with size of 3 and inputs of 1, 2, and 3, and I get as output: 1->2->3->
You got two problems.
else if (count != 0)
{
node * temp = prev;
temp = (node * ) malloc(sizeof(node));
temp-> freq = data;
temp-> next = NULL;
prev-> next = temp;
}
You aren't changing prev to point to your new node. It still points to '2' in your scenario, and you'll never have more than two nodes in the list.
Try something like
else if (count != 0)
{
/* node * temp = prev; */ //This code is not doing anything useful
temp = (node * ) malloc(sizeof(node));
temp-> freq = data;
temp-> next = NULL;
prev-> next = temp;
prev = temp;
}
Next, your printing loop should probably be
node* temp1 = start; //You need a variable that points to the first node in the list
do
{
printf("%d-> ", temp1-> freq);
temp1 = temp1-> next;
}
//The last item will always have next == NULL, and must be included
while (temp1-> next != NULL);

Singly linked list in c

below is my code for singly linked list in c. Can anyone help me with this?
this is my main c file:
#include <stdio.h>
#include <stdlib.h>
#include "myclib.c"
struct mydata
{
int num;
char name;
struct mydata *next;
};
int main()
{
struct mydata *head, *newnode, *temp;
head = (struct mydata*)malloc(sizeof(struct mydata));
newnode = (struct mydata*)malloc(sizeof(struct mydata));
temp = (struct mydata*)malloc(sizeof(struct mydata));
head -> num = 123;
head -> name = 'k';
head -> next = NULL;
newnode -> num = 456;
newnode -> name = 'd';
newnode -> next = NULL;
printf("before.app.head = %p\n",head);
printf("before.app.newnode = %p\n",newnode);
printf("before.app.head->next = %p\n",head -> next);
printf("before.app.newnode->next = %p\n",newnode -> next);
head = (struct mydata*)addNodeAtHead(head, newnode, (newnode -> next));
printf("after.app.head = %p\n",head);
printf("after.app.newnode = %p\n",newnode);
printf("after.app.head->next = %p\n",head -> next);
printf("after.app.node->next = %p\n",newnode -> next);
temp = head;
while(temp != NULL)
{
printf("num : %d\n",temp -> num);
printf("name : %c\n",temp -> name);
temp = temp -> next;
}
free(temp);
free(head);
return 0;
}
this is myclib.c file:
#include <stdio.h>
void * addNodeAtHead(void *head, void *node, void *nodenext)
{
printf("\nbefore.head = %p\n",head);
printf("before.node = %p\n",node);
printf("before.nodenext = %p\n",nodenext);
nodenext = head;
head = node;
printf("after.head = %p\n",head);
printf("after.node = %p\n",node);
printf("after.nodenext = %p\n\n",nodenext);
return head;
}
i am trying to add newnode in front of head and than changing head pointer to newnode.
#include <stdio.h>
#include <stdlib.h>
//#include "myclib.c"
struct mydata
{
int num;
char name;
struct mydata *next;
};
struct mydata* addNodeAtHead(struct mydata* head, struct mydata* node)
{
#ifdef DEBUG
printf("\nbefore.head = %p\n",head);
printf("before.node = %p\n",node);
// printf("before.nodenext = %p\n",nodenext);
#endif
if(node){
node->next = head;
head = node;
}
#ifdef DEBUG
printf("after.head = %p\n",head);
printf("after.node = %p\n",node);
// printf("after.nodenext = %p\n\n",nodenext);
#endif
return head;
}
int main()
{
struct mydata *head, *newnode, *temp;
head = (struct mydata*)malloc(sizeof(struct mydata));
newnode = (struct mydata*)malloc(sizeof(struct mydata));
//temp = (struct mydata*)malloc(sizeof(struct mydata));//unused and rewrite to other pointer
head -> num = 123;
head -> name = 'k';
head -> next = NULL;
newnode -> num = 456;
newnode -> name = 'd';
newnode -> next = NULL;
#ifdef DEBUG
printf("before.app.head = %p\n",head);
printf("before.app.newnode = %p\n",newnode);
printf("before.app.head->next = %p\n",head -> next);
printf("before.app.newnode->next = %p\n",newnode -> next);
#endif
head = (struct mydata*)addNodeAtHead(head, newnode);
#ifdef DEBUG
printf("after.app.head = %p\n",head);
printf("after.app.newnode = %p\n",newnode);
printf("after.app.head->next = %p\n",head -> next);
printf("after.app.node->next = %p\n",newnode -> next);
#endif
temp = head;
while(temp != NULL)
{
printf("num : %d\n",temp -> num);
printf("name : %c\n",temp -> name);
temp = temp -> next;
}
/*
free(temp);//NULL
free(newnode);//...
free(head);//already changed
*/
temp=head;
while(temp != NULL){
struct mydata *prev = temp;
temp=temp->next;
free(prev);
}
return 0;
}
When you are passing (newnode -> next) to the function addNodeAtHead. The value of (newnode -> next) is copied to the node variable in the function. And you are updating that node variable with new value head. After the execution of the function node variable get destroyed and has no relation with (newnode -> next). And so (newnode -> next) remains unchanged.
To over come it, just change your addNodeAtHead like bellow:
void * addNodeAtHead(void *head, void *node)
{
printf("\nbefore.head = %p\n",head);
printf("before.node = %p\n",node);
((mydata *)node)-> next = (mydata *) head;
printf("after.head = %p\n",head);
printf("after.node = %p\n",node);
return node;
}
And call it simply like:
head = (struct mydata*)addNodeAtHead(head, newnode);
And Everything should be okay now.
You need to set the next pointer on the added node to point to the original head node.
I changed the signature of addNodeAtHead: You should not pass void * when you are alyway passing pointers of the type mydata *. I also change the variable names to be more clear (IMO) about their purpose
mydata * addNodeAtHead(mydata * original_head, mydata * new_node)
{
new_node -> next = original_head;
return new_node; // new_node is now the head of the list!
}
**PROGRAM ON SINGLY LINKER LIST ( CREATION AND TRAVERSING WITH COMMENTS )**
#include<stdio.h> //Header file for input and output operations.
#include<conio.h>
struct node // structure declaration .
{
int info; // stores information.
struct node *link; // stores the address of next link.
};
struct node *first; // used to point to the first node.
void create(); // function call |NOTE| This line is optional.
void traverse(); // function call |NOTE| This line is optional.
int main() // main function.
{
create(); // function call for creation.
traverse(); // function call for traversing i.e nothing but display.
return 0;
}
void create() // declaration of create function , creation of nodes.
{
char ch; // variable to take an input from the user for decision.
struct node *ptr,*cpt; // these are used to create a node and referred to as
//previous pointer and current pointer.
ptr=(struct node*)malloc(sizeof(struct node)); //dynamic declaration
printf("Enter data into the first node \n");
scanf("%d",&ptr->info); // taking the input from the user.
first=ptr; //assigning the information taken from previous pointer to first for
//future identification.
do // loop which continuously generates and links new nodes to previous nodes.
{
cpt=(struct node*)malloc(sizeof(struct node)); //dynamic declaration of current
//pointer.
printf("Enter the data for another node \n");
scanf("%d",&cpt->info); // getting input from the user of next node
// information.
ptr->link=cpt; // linking the previous pointer to the new pointer.
ptr=cpt; // transferring the previous node information to the current node
//i.e previous pointer to the current pointer.
printf("Do you want to create another node <Y/N>:\n\n");
ch=getch(); // getting the users decision.
}
while(ch=='y'); // checking the users decision.
ptr->link=NULL; // assigning the previous pointer link to null;
}
void traverse() // function declaration of display or traversing.
{
int count=1; // counting variable for naming the nodes.
struct node *ptr; // pointer variable used for traversing.
ptr=first; // assigning ptr to the first for starting traversing from the
//first node.
printf("TRAVERSING OF A LINKED LIST \n");
while(ptr!=NULL) // checking whether the ptr is null or not, And if not
//executes the statements written in the body.
{
printf("The data stored in node %d is:%d \n",count,ptr->info); //prints the
// node id and information present in the node.
ptr=ptr->link; // This statement is used to traverse to the next node.
count++; // count incrementation.
}
}
// f☺ll☺w ☺n instagram ♥ ---> #cyber_saviour
//------ SINGLY LINKED LIST PROGRAM ( CREATION AND TRAVERSING ) -------X
#include<stdio.h>
#include<conio.h>
struct node
{
int info;
struct node *link;
};
struct node *first;
int main()
{
void create();
void traverse();
create();
traverse();
return 0;
}
void create()
{
struct node *cpt,*ptr;
char ch;
ptr=(struct node*)malloc(sizeof(struct node));
printf("enter the data \n");
scanf("%d",&ptr->info);
first=ptr;
do
{
cpt=(struct node*)malloc(sizeof(struct node));
printf("enter the data \n");
scanf("%d",&cpt->info);
ptr->link=cpt;
ptr=cpt;
printf("Do you want to create a new node <Y/N> :\n");
ch=getch();
}
while(ch=='y');
ptr->link=NULL;
}
void traverse()
{
struct node *ptr;
ptr=first;
while(ptr!=NULL)
{
printf("The entered nodes are:%d \n",ptr->info);
ptr=ptr->link;
}
}
#include <stdio.h>
void addNodeAtHead(void **head, void *node){
void *prH=*head;
*head=node;
node->next=prH;
}

Resources