Linked List from Linked List - c

I am trying to create an (ordered) linked list of (ordered) linked lists. The list-of-list links are carried by the first nodes of its member lists. I am trying to achieve this via the following code, but my program crashes when I try displaying the second list. First list displays perfectly.
Here's a schematic of the data structure I am trying to construct:
Code:
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
struct node{
int number;
struct node*next;
struct node*lsnext;
};
typedef struct node Node;
Node* insertValue(Node * list, int value);
void display(Node*);
Node* insertArr(Node * list, int value);
Node* addNodeBottom(int val, Node *start);
int main()
{
Node *globalList = NULL, *lists,*start,*save;
int nbrOfLists, listNo, nbrOfVal, valNo, val;
start=NULL;
printf("\n Enter the number of lists:");
scanf("%d", &nbrOfLists);
if(nbrOfLists < 0)
return -1;
for(listNo = 0; listNo < nbrOfLists; listNo++)
{
printf("\n\n Enter the number of inputs to the list %d: \n ",listNo+1);
scanf("%d", &nbrOfVal);
lists = NULL;
for(valNo = 0; valNo < nbrOfVal; valNo++)
{
printf("Enter node value %d:", valNo+1);
scanf("%d", &val);
// Here we insert the value in both lists
lists= insertValue(lists, val);
globalList = insertValue(globalList, val);
}
start=addNodeBottom(val,lists);
if(listNo==0){
save=start;
}
printf("\n The list %d is: ",listNo+1);
display(lists);
}
printf("\n\n The final list is: ");
display(globalList);
printf("The first list is");
display(save);
printf("The second list is");
display(save->lsnext); //crashes here
return 0;
}
Node* insertValue(Node * list, int value) //to insert node at the end
{
Node *newNode, *m;
newNode = malloc(sizeof(Node));
newNode->number=value;
if(list == NULL)
{
newNode->next=NULL;
return newNode;
}
if(value < list->number)
{
newNode->next = list;
return newNode;
}
m = list;
while(m->next)
{
if(value < m->next->number)
break;
m = m->next;
}
newNode->next = m->next;
m->next = newNode;
return list;
}
Node* addNodeBottom(int val, Node *start)
{
Node*rear;
Node* node1=(Node*) malloc(sizeof(Node));
node1->number=val;
node1->lsnext=NULL;
if(start==NULL){
start=rear=node1;
}
else{
rear->lsnext=node1;
rear=node1;
}
return start;
}
void display(Node*nodex){
while(nodex)
{
printf("%d ->",nodex->number);
nodex=nodex->next;
}
}

This code invokes undefined behaviour. In particular, your function addNodeBottom is buggy: If invoked with start not NULL, it modifies the member rear->lsnext, but rear is uninitialised at that point. I assume, you intended to modify start instead. Here, you return start unmodified, so it's member lsnext is not set to anything useful, which probably eventually leads to a segmentation fault. However, in principle already the offending function call to addNodeBottom could lead to unexpected program termination.

Related

new to lists, function doesn't print list elements

I am a beginner to C and am learning linked lists. I tried making functions to have everything organised but no matter what i do the function print_list doesn't print the values. The output is only START and END. I noticed that if I put the same block of code directly into the function that builds the lists, then it prints correctly. What am I doing wrong? (Also first time asking on stack overflow)
Thank you to whoever answers.
#include <stdlib.h>
#include <stdio.h>
typedef struct nd
{
int val;
struct nd *next;
} node;
typedef node * Lista;
void print_list(node*currnode)
{
printf("START -> ");
while (currnode != NULL)
{
printf("%d -> ", currnode->val);
currnode = currnode->next;
}
printf("END");
}
//reimpilista means "buildlist"
node*riempilista(Lista lis){
node *currentNode, *temp;
int i,n;
printf("how many nodes?\n");
scanf("%d",&n);
for (i = 0; i < n; i++)
{
currentNode = (node *)malloc(sizeof(node));
printf("Enter element %d : ", (i + 1));
scanf("%d", &currentNode->val);
if (i == 0)
{
temp = currentNode;
}
else
{
temp->next = currentNode;
temp = currentNode;
}
}
temp->next = NULL;
return lis;
}
int main(){
Lista listautente=NULL;
listautente=riempilista(listautente);
print_list(listautente);
return 0;
}
When you build the list you need to return the head of the list as a result. So you need to store the pointer to the first node. Then when adding a new node you need to know the previous node, so you need to store it as well. The last added node should have next field poiting to NULL otherwise you won't be able to determine the end of the list and will get an exception.
Here is your code slightly edited.
#include <stdlib.h>
#include <stdio.h>
typedef struct nd {
int val;
struct nd *next;
} node;
typedef node *Lista;
void print_list(node *currnode) {
printf("START -> ");
while (currnode != NULL) {
printf("%d -> ", currnode->val);
currnode = currnode->next;
}
printf("END");
}
//reimpilista means "buildlist"
node *riempilista() {
node *firstNode = NULL, *currentNode = NULL, *previousNode = NULL;
int i, n;
printf("how many nodes?\n");
scanf("%d", &n);
for (i = 0; i < n; ++i) {
currentNode = (node *)malloc(sizeof(node));
printf("Enter element %d : ", (i + 1));
scanf("%d", &currentNode->val);
currentNode->next = NULL;
if (i == 0) {
firstNode = currentNode;
}
if (previousNode != NULL) {
previousNode->next = currentNode;
}
previousNode = currentNode;
}
return firstNode;
}
int main() {
Lista listautente = riempilista();
print_list(listautente);
return 0;
}
I tried to fix your program with minimal changes. Here it is:
Change
node *currentNode, *temp;
to
node *currentNode, *temp, *head;
Change
temp = currentNode;
to
temp = currentNode; head = temp;
Change
return lis;
to
return head;
Here is the link to the modified code:
https://onlinegdb.com/8cjqifgl2

Error in a simple program of entering elements at beginning of a linkedlist and displaying it in c programming

This is my code for program to enter elements in beginning of a linked list and print the linked list which is working perfectly fine(i am getting correct output for it) -
#include <stdio.h>
#include <stdlib.h>
// this is insertion of a node in begining of a linked list
typedef struct Node
{
int data;
struct Node *next;
} n;
void Insert(struct Node** head,int x)
{
struct Node *temp = (n *)malloc(sizeof(struct Node));
temp->data = x;
temp->next = *head;
*head = temp;
}
void Print(struct Node* head)
{
struct Node *temp = head;
printf("The linked list is:");
while (temp != NULL)
{
printf("%d,", temp->data);
temp = temp->next;
}
printf("\n");
}
int main()
{
struct Node *head;
head = NULL;
int n, i, x;
printf("Enter how many numbers you want?\n");
scanf("%d", &n);
for (i = 0; i < n; i++)
{
printf("Enter the number in the linkedlist\n");
scanf("%d", &x);
Insert(&head,x);
Print(head);
}
return 0;
}
for context the output is
Enter how many numbers you want?
6
Enter the number in the linkedlist
1
The linked list is:1,
Enter the number in the linkedlist
2
The linked list is:2,1,
Enter the number in the linkedlist
3
The linked list is:3,2,1,
Enter the number in the linkedlist
4
The linked list is:4,3,2,1,
Enter the number in the linkedlist
5
The linked list is:5,4,3,2,1,
Enter the number in the linkedlist
6
The linked list is:6,5,4,3,2,1,
now just to see if my concepts of pointers and pointer to structure is clear i modified the Print() function in code as while rest of he program remain same
#include <stdio.h>
#include <stdlib.h>
// this is insertion of a node in begining of a linked list
typedef struct Node
{
int data;
struct Node *next;
} n;
void Insert(struct Node** head,int x)
{
struct Node *temp = (n *)malloc(sizeof(struct Node));
temp->data = x;
temp->next = *head;
*head = temp;
}
void Print(struct Node* head)
{
struct Node *temp = head;
printf("The linked list is:");
// while (temp != NULL)
// {
// printf("%d,", temp->data);
// temp = temp->next;
// }
// printf("\n");
do{
printf("%d,", temp->data);
temp = temp->next;
}while((temp->next)!= NULL);
printf("\n");
}
int main()
{
struct Node *head;
head = NULL;
int n, i, x;
printf("Enter how many numbers you want?\n");
scanf("%d", &n);
for (i = 0; i < n; i++)
{
printf("Enter the number in the linkedlist\n");
scanf("%d", &x);
Insert(&head,x);
Print(head);
}
Print(head);
return 0;
}
Now while i did the dry run where i am getting correct result ,the output i am getting is wrong,for context the output coming is
Enter how many numbers you want?
5
Enter the number in the linkedlist
1
The linked list is:1,
--------------------------------
Process exited after 5.156 seconds with return value 3221225477
Press any key to continue . . .
while i only made changes in Print() function why is'nt the compiler accepting the rest of the elements in linkedlist as input ? assuming there is some mistake in Print() function
Such function implementation
void Print(struct Node* head)
{
struct Node *temp = head;
printf("The linked list is:");
// while (temp != NULL)
// {
// printf("%d,", temp->data);
// temp = temp->next;
// }
// printf("\n");
do{
printf("%d,", temp->data);
temp = temp->next;
}while((temp->next)!= NULL);
printf("\n");
}
is incorrect.
Firstly it does not check whether the passed pointer is equal to NULL.
Secondly the condition in the do-while loop
}while((temp->next)!= NULL);
can invoke undefined behavior if after this statement within the loop
temp = temp->next;
the pointer temp again is equal to NULL (when the list contains one node). Because in this case a null pointer is used to access memory. Or in other case when the list contains more than one node the last node will not be outputted.

Linked list unable to print all elements

I'm trying to print the linked list to which I prompt for user input.
This code below is not printing the whole list, only the last element at a time.
I don't seem to find the bug. Can you please take a look at it?
#include <stdio.h>
#include <stdlib.h>
struct Node {
int data;
struct Node *next;
};
struct Node *head;
void Insert(int x) {
struct Node *temp = (struct Node *)malloc(sizeof(struct Node));
temp->data = x;
temp->next = NULL;
head = temp;
};
void Print() {
struct Node *temp = head;
printf("Linked list is: ");
while (temp != NULL) {
printf("%d ", temp->data);
temp = temp->next;
}
printf("\n");
};
int main() {
head = NULL;
int i, x;
for (i = 1; i <= 10; i++) {
if (i == 1) {
printf("Enter 1st number: \n");
} else if (i == 2) {
printf("Enter 2nd number: \n");
} else {
printf("Enter %dth number: \n", i);
}
scanf("%d", &x);
Insert(x);
Print();
}
}
temp->next = NULL; is the culprit. It should be temp->next = head;.
Another (more cornercase) issue is that your code fails to check for errors in malloc and scanf.
Edit in response to comment:
If you want to append (as opposed to prepend), you'll need to keep a tail pointer for forward traversal and then either use a dummy first node (avoids a branch) or special-case an insert to an empty list.
Example of both (with simplistic error handling via exit(1)) in one piece of code:
#include <stdio.h>
#include <stdlib.h>
struct Node {
int data;
struct Node *next;
};
#define DUMMYFIRST 1 //change to 0 to compile the other variant
#if DUMMYFIRST
struct Node dummyfirst;
struct Node *head=&dummyfirst;
#else
struct Node *tail,*head=0;
#endif
void Insert(int x) {
struct Node *newnode = malloc(sizeof(struct Node));
//don't cast the result of malloc in C
//https://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc
if(!newnode) { perror("malloc"); exit(1); }
newnode->data = x;
newnode->next = 0;
#if !DUMMYFIRST
if(!tail) tail = head = newnode;
else head->next = newnode;
#else
head->next = newnode;
#endif
head = newnode;
};
void Print() {
#if DUMMYFIRST
struct Node *newnode = dummyfirst.next;
#else
struct Node *newnode = tail;
#endif
printf("Linked list is: ");
while (newnode != NULL) {
printf("%d ", newnode->data);
newnode = newnode->next;
}
printf("\n");
};
int main() {
int i, x;
for (i = 1; i <= 10; i++) {
if (i == 1) {
printf("Enter 1st number: \n");
} else if (i == 2) {
printf("Enter 2nd number: \n");
} else {
printf("Enter %dth number: \n", i);
}
if(1!=scanf("%d", &x)) exit(1);
Insert(x);
Print();
}
}
A more library friendly approach to handling errors would be to propagate the error to the caller, i.e., instead of exiting with an error message right away, you'd change the return value from void to something indicating the error, e.g. so that the caller could check and decide what to do (print it, print it in a localized version, try a different algorithm...)
E.g.:
struct Node *Insert(int x) {
struct Node *newnode = malloc(sizeof(struct Node));
//don't cast the result of malloc in c
//https://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc
if(!newnode) return NULL;
//...
};
//...
//calling code:
if(!Insert(x)) perror("Insert"),exit(1);
When you insert the new node, you do not link the rest of the list, instead of temp->next = NULL; you should write
temp->next = head;
To ensure defined behavior, you should check for memory allocation failure and invalid input.
Also remove the dummy ; after the function bodies.
Here is a modified version:
#include <stdio.h>
#include <stdlib.h>
struct Node {
int data;
struct Node *next;
};
struct Node *head;
int Insert(int x) {
struct Node *temp = malloc(sizeof(*temp));
if (temp) {
temp->data = x;
temp->next = head;
head = temp;
return 1;
} else {
return 0;
}
}
void Print(void) {
struct Node *temp = head;
printf("Linked list is: ");
while (temp != NULL) {
printf("%d ", temp->data);
temp = temp->next;
}
printf("\n");
}
int main() {
static char suffix[4][3] = { "th", "st", "nd", "rd" };
int i, x;
for (i = 1; i <= 10; i++) {
int suff = (i >= 1 && i <= 3) ? i : 0;
printf("Enter %d%s number:\n", i, suffix[suff]);
if (scanf("%d", &x) != 1) {
fprintf(stderr, "invalid or missing input\n");
break;
}
if (!Insert(x)) {
fprintf(stderr, "cannot allocate memory for Node\n");
return 1;
}
Print();
}
return 0;
}

Freeing memory after returning from a function

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
//defined a data structure "node" which stores an int and a pointer to a node
typedef struct node
{
int number;
struct node *next;
}
node;
//defining functions
node* create(int number);
node* insert(node *new_linked_list, int number);
void print(node *new_linked_list);
void delete_list(node *new_linked_list);
int main(void)
{
//create new linked list with function
node *new_linked_list = NULL;
//get input to update list
for (int i = 0; i < 10; i++)
{
int temp;
if (i == 0)
{
scanf(" %i", &temp);
printf("\n");
new_linked_list = create(temp);
continue;
}
//will insert new nodes in the linked lists
scanf(" %i", &temp);
printf("\n");
new_linked_list = insert(new_linked_list, temp);
}
//prints node number values out
print(new_linked_list);
//delete/free list
delete_list(new_linked_list);
}
//function will return a pointer to the first node in the list
node* create(int number)
{
node *firstnode = malloc(sizeof(node));
firstnode -> number = number;
firstnode -> next = NULL;
return firstnode;
}
//function that will update the linked list and return a pointer to the new head of the linked list
node* insert(node *new_linked_list, int number)
{
node* new_node = malloc(sizeof(node));
if (new_node == NULL)
{
return new_linked_list;
}
//new node will point to the old first node and updates new_nodes number
new_node -> number = number;
new_node -> next = new_linked_list;
//returns a pointer to the new first node
return new_node;
}
void print(node *new_linked_list)
{
//temporary node for reversal
node *trav = new_linked_list;
for (int i = 0; i < 10; i++)
{
printf("%i ",trav -> number);
trav = trav -> next;
if (i == 9)
{
printf("\n");
}
}
}
void delete_list(node *new_linked_list)
{
//base case: at null pointer
if (new_linked_list -> next == NULL)
{
//frees memory previously allocated to a pointer
free(new_linked_list);
return;
}
//else delete the rest of the list
else
{
delete_list(new_linked_list -> next);
}
}
Hi so I was experimenting with a linked list and came across a problem. My program leaks memory because I am not freeing the "new node". However, I'm confused on how to free it as it is being return to be used in main. How would I go about freeing "new node" while still being able to use it in the main function. Thank you for any help in advance.
The issue seems to be related to the recursive behaviour of 'delete_list'
It could be implemented like the following:
void delete_list(node *new_linked_list)
{
node *next;
while(new_linked_list != NULL)
{
next = new_linked_list->next;
free(new_linked_list);
new_linked_list = next;
}
}

C infinite loop with linked list

I am trying to make a program that initialize a singular linked list and then ask user for more data and add them at the end of current linked list. However, my programming is trapped in infinite loop.
#include <stdio.h>
#include <stdlib.h>
typedef struct linked_list
{
int data;
struct linked_list *next;
}element;
typedef element *elementptr;
void addend(elementptr *,int);
void traverse(elementptr);
int main()
{
// create a linked list
elementptr first = NULL,
last = NULL;
int input,num;
printf("Please enter first integer data: \n");
scanf("%d",&input);
//Create a linked list with user initialized data
first = (elementptr)malloc(sizeof(element));
last = first;
last -> data = input;
last -> next = NULL;
printf("Please enter number of data you want to add in the end of linked list\n");
scanf("%d",&num);
addend(&last,num);
traverse(first);
return 0;
}
void addend(elementptr *l, int num)
{
int i = 0,extradata;
while(i<num)
{
i++;
printf("Please enter a data: \n");
scanf("%d",&extradata);
(*l) -> next = (elementptr)malloc(sizeof(element));
*l = (*l) ->next;
(*l) -> data = extradata;
(*l) -> next = NULL;
}
printf("The data sets are added\n");
}
void traverse(elementptr f)
{
elementptr current;
int count = 0;
current = f;
while (current != NULL)
{
count++;
printf("The data is %d \n", current->data);
}
printf("The linked list has %d elements \n",count);
}
In your code
while (current != NULL)
{
count++;
printf("The data is %d \n", current->data);
}
you never change the value of current. Either it starts as NULL and the loop never executes, or it starts non-NULL and the loop runs forever.
You should add
current = current->next
after your printf to advance to the next element in the linked list.
current = current -> next; you are missing this statement in the while loop. Although I would suggest :
#include<stdio.h>
#include<stdlib.h>
struct linked_list
{
int number;
struct linked_list *next;
struct linked_list *prev;
};
typedef struct linked_list node;
void create(node *p);
void print(node *p);
int main()
{
node *head;
printf("---Start of the list ---\n");
printf("enter -1 to exit\n");
head = (node*)malloc(sizeof(node));
create(head);
print(head);
}
void create(node *list)
{
printf("enter the data");
scanf(" %d",&list->number);
if(list->number == -1)//Enter -1 to exit untill then keep on taking values
{
list->next=NULL;
}
else
{
list->next = (node*)malloc(sizeof(node));
create(list->next);
}
}
void print(node *list)
{
if(list->next != NULL)
{
printf("%d-->",list->number);
if((list->next->next == NULL) && (list->next->number!=-1))
printf("%d -->End of the List",list->next->number);
print(list->next);
}
}
In your traverse function, the current node is not pointing to next node. So the while condition while (current != NULL) will not be true and hence the while loop is running infinitely.
To fix it, current node should point to the next node (current = current->next) in the list after printing the data.
For example:
void traverse(elementptr f)
{
elementptr current;
int count = 0;
current = f;
while (current != NULL)
{
count++;
printf("The data is %d \n", current->data);
// Fix
current = current->next; // Point to next node in link list
}
}

Resources