Printing a Linked list by users input - c

I am a beginner and I am attending to create and print a linked list by users input. Creating part goes well, but every time I try to print the final list, I get the annoying "LIST IS EMPTY" message. There is probably a problem with *stnode pointer. Could anybody help me please? Thanks for every answer!
Code
#include <stdio.h>
#include <stdlib.h>
struct node
{
int data;
struct node *next;
}*stnode;
//function creating the linked list
void createnodelist(int n)
{
int num, i;
struct node *stnode = (struct node*)malloc(sizeof(struct node)), *fnnode, *temp;
if (stnode==NULL) {
printf("Memory cannot be located");
return;
}
//creating head of the list
else {
printf("Number 1 = ");
scanf("%d", &num);
stnode->data = num;
stnode->next = NULL;
if (stnode == NULL) {
printf("Memory can not be located");
}
temp = stnode;
}
//Creating all others parts of linked list
for (i=2; i<=n; i++)
{
fnnode = (struct node*)malloc(sizeof(struct node));
if (fnnode==NULL) {
printf("Memory cannot be located\n");
break;
}
printf("Number %d = ", i);
scanf("%d", &num);
fnnode->data = num;
fnnode->next = NULL;
temp->next = fnnode;
temp = temp->next;
}
}
//function printing the output
void printnode()
{
struct node *n = (struct node*)malloc(sizeof(struct node));
n = stnode;
if (stnode == NULL) {
printf("LIST IS EMPTY"); //HERE IS MY PROBLEM
}
while (n!=NULL) {
printf("%d ", n->data);
n = n->next;
}
}
int main()
{
int n;
printf("Enter number of elements: ");
scanf("%d", &n);
printf("\n");
createnodelist(n);
printf("\n");
printnode();
printf("\n\n");
return 0;
}

In createnotelist(), you are hiding the global stnode with the local declaration of the stnode. Because of that, the global stnode is remaining undefined or null and is not being modified in createnodelist().

Your createnodelist function does nothing (except leak memory).
It declares a local variable called stnode:
struct node *stnode = (struct node*)malloc(sizeof(struct node)), *fnnode, *temp;
But that local variable is destroyed when the function returns, so there's no way to access the list you've built.
In particular, this stnode is unrelated to the global variable of the same name.
Your printnode function does this:
struct node *n = (struct node*)malloc(sizeof(struct node));
n = stnode;
(Note that this is a memory leak: n = stnode overwrites the pointer returned from malloc, which has now become inaccessible and cannot be freed.)
This stnode is a global variable. It was never set, so it still contains its initial value of NULL.

In createnodelist, write
void createnodelist(int n)
{
int num, i;
stnode = (struct node*)malloc(sizeof(struct node));
struct node *fnnode, *temp;
instead of
void createnodelist(int n) {
int num, i;
struct node *stnode = (struct node*)malloc(sizeof(struct node)), *fnnode, *temp;
Otherwise, you introduce a local variable, which hides the global stnode used in your printnode function later on.
BTW: struct node *n = (struct node*)malloc(sizeof(struct node)); in printnode is superflous, since you overwrite the value of n in the next statement; Writing struct node *n = stnode instead is sufficient.

Related

Function is unable to enter the for loop in the problem Intersection of two linked lists

I am working on a problem that gives two sorted linked lists and asks to find the intersection of two lists and create a new list with the elements as the common elements.
I am attaching my code.
#include<stdio.h>
#include<stdlib.h>
struct node{
int val;
struct node *next;
};
void getval(struct node *p)
{
scanf("%d",&p->val);
p->next=NULL;
}
void createlist(struct node **p , int n)
{
int i=0;
struct node *str =NULL;
for( i=0;i<n;i++)
{
if(*p==NULL)
{
*p = (struct node*)malloc(sizeof(struct node));
str = (struct node*)malloc(sizeof(struct node));
*p = str;
getval(*p);
}
else
{
str->next = (struct node*)malloc(sizeof(struct node));
getval(str->next);
str=str->next;
}
if(i==n-1)
{
str=NULL;
}
}
}
void intersectlist(struct node *p1 , struct node *p2 )
{
int i=0,j=0;
struct node *head3=NULL;
struct node *str= NULL;
struct node *p3= NULL;
for(i=0;p1!=NULL;i++)
{
p3=p2;
for(j=0;p3!=NULL;j++)
{
if(p1->val == p3->val)
{
if(head3==NULL)
{
head3 = (struct node*)malloc(sizeof(struct node));
str = (struct node*)malloc(sizeof(struct node));
head3 = str;
head3->val=p3->val;
}
else
{
str->next = (struct node*)malloc(sizeof(struct node));
str->val = p3->val;
str=str->next;
}
break;
}
p3=p3->next;
}
p1= p1->next;
}
str = NULL;
struct node *p = NULL;
p=head3;
while(p!=NULL)
{
printf("%d ",p->val);
p=p->next;
}
}
int main(){
struct node *head1=NULL;
struct node *head2=NULL;
int i,a=0,n1=0,n2=0;
printf("enter the size of list 1 :");
scanf("%d",&n1);
printf("enter the elements of list 1 :");
createlist(&head1,n1);
printf("enter the size of list 2 :");
scanf("%d",&n2);
printf("enter the elements of list 2 : ");
createlist(&head2,n2);
intersectlist(head1 , head2);
return 0;
}
Here in the function intersectlist, even though p1( which is head1) is not null, the function doesn't enter the loop. It simply exits the loop and jumps directly to the line (str=NULL). Why is this happening
Here in the function intersectlist, even though p1( which is head1) is not null, the function doesn't enter the loop.
That is no true. I compiled and ran your program and both loops where entered.
Yet, the result is wrong.
The problem is your code to copy the found duplicates into the new list:
if(head3==NULL)
{
head3 = (struct node*)malloc(sizeof(struct node));
str = (struct node*)malloc(sizeof(struct node));
head3 = str;
head3->val=p3->val;
}
else
{
str->next = (struct node*)malloc(sizeof(struct node));
str->val = p3->val;
str=str->next;
}
Here, first of all in the if branch you create a memory leak by allocating memory for head3. 2 lines later you overwrite that address by another value and you can never free that first one. The same error exists in your function to create the lists.
Then your main error happens in the else part:
You overwrite the value from first node with value from the new node. Remember: str still holds the address of head3 when you come here for the first time. You must advance the pointer first and afterwards assign content.
Then, you have another problem as you do not terminate your new list.
You seem to intent to do it with str = NULL; after your loops but that does not help. You only assign to str, not to str->next.
Besides that, you have ununsed variables in main. Also the loop variables i and j are completely useless. You only use pointers in your loop, no need to mess with additional counters.
Your loops could look like this to do the very same:
for( ; p1 != NULL; )
{
p3=p2;
for( ; p3 != NULL; )
And if you don't have initialization and end-of-loop operation, then you could just use while loops instead.
All in all a fixed version looks like this:
#include<stdio.h>
#include<stdlib.h>
struct node{
int val;
struct node *next;
};
void getval(struct node *p)
{
scanf("%d",&p->val);
p->next=NULL;
}
void createlist(struct node **p , int n)
{
int i=0;
struct node *str =NULL;
for (i=0;i<n;i++)
{
if (*p==NULL)
{
str = malloc(sizeof(struct node));
*p = str;
getval(*p);
}
else
{
str->next = malloc(sizeof(struct node));
getval(str->next);
str=str->next;
}
if (i==n-1)
{
str=NULL;
}
}
}
void intersectlist(struct node *p1 , struct node *p2 )
{
struct node *head3=NULL;
struct node *str= NULL;
struct node *p3= NULL;
whlie (p1 != NULL)
{
p3=p2;
while (p3 != NULL)
{
if (p1->val == p3->val)
{
if (head3==NULL)
{
str = malloc(sizeof(struct node));
head3 = str;
head3->val=p3->val;
}
else
{
str->next = malloc(sizeof(struct node));
str=str->next;
str->val = p3->val;
str->next = NULL;
}
break;
}
p3=p3->next;
}
p1= p1->next;
}
struct node *p = head3;
while (p!=NULL)
{
printf("%d ",p->val);
p=p->next;
}
printf("\n");
}
int main(void)
{
struct node *head1=NULL;
struct node *head2=NULL;
int n1=0,n2=0;
printf("enter the size of list 1 :");
scanf("%d",&n1);
printf("enter the elements of list 1 :");
createlist(&head1,n1);
printf("enter the size of list 2 :");
scanf("%d",&n2);
printf("enter the elements of list 2 : ");
createlist(&head2,n2);
intersectlist(head1 , head2);
return 0;
}
output:
enter the size of list 1 :3
enter the elements of list 1 :2 3 4
enter the size of list 2 :4
enter the elements of list 2 : 2 4 6 7
2 4
Additional hints:
Both lists are sorted. Therefore you wouldn't need to start the inner loop from head of second list each time. Instead you might just continue where you left the inner loop last time.
Mixing list management (p->next=NULL;) with entering payload isn't really straight forward. Instead you should put that line to where you allocate and link the nodes for your list. Otherwise it will confuse readers. Remember: A while after writing some code you will also just be a reader of that code and will get confused as well.
Also, in C you do not need to cast return value of malloc and you should not do it. A cast might hide errors that the compiler could detect otherwise.

Error: in creation of Linked List Display function

I am trying to create a linked list with display() function in it but i continuously getting error in it. a function not able to display element in output.
I have try various online solution of code but not worked on my code.
Below is my code if anyone have any idea. let me tell to solve it
#include <stdio.h>
#include <stdlib.h>
struct node{
int data;
struct node *next;
};
int create(int n){
int d1,d2,i;
struct node *head, *temp, *newnode;
head = (struct node *) malloc(sizeof(struct node));
printf("enter the data for node 1");
scanf("%d",&d1);
head->data = d1;
head->next = NULL;
temp = head;
for(i=2; i<=n; i++){
newnode = (struct node *)malloc(sizeof(struct node));
printf("enter a data for %d node",i);
scanf("%d",&d2);
newnode->data = d2;
newnode->next = NULL;
temp->next = newnode;
temp = temp->next; // newnode can also use instead of temp->next
}
void printList(struct node* node) {
while (node != NULL) {
printf(" %d ", node->data);
node = node->next;
}
}
}
int main()
{
struct node* head = NULL;
int n;
printf("Enter number of node to create");
scanf("%d",&n);
create(n);
printList(head);
return 0;
}
Change return type of the create function to return the address of the node like this: struct node * create(int n) and change return value to: return head;.
Finally, in main() save the returned address in head pointer: head = create(n);

Print function messes up the linked list

#include <stdio.h>
#include <stdlib.h>
struct Node
{
int val;
struct Node *next;
};
struct List
{
struct Node *head;
struct Node *tail;
};
typedef struct List *List;
void Print(List temp)
{
struct Node* print = temp->head;
while(print->next!=NULL)
{
printf("%d ", print->next->val);
print->next = print->next->next;
}
printf("\n\n");
}
int main()
{
int i;
List Numbers;
Numbers = (struct List *) malloc(sizeof(struct List));
if (Numbers== NULL)
printf("Out of memory!\n");
Numbers->head = (struct Node *) malloc(sizeof(struct Node));
if (Numbers->head == NULL)
printf("Out of memory!\n");
Numbers->head->next = NULL;
Numbers->tail = Numbers->head;
printf("Enter 5 numbers:");
struct Node* temp = Numbers->head;
for(i=0;i<5;i++)
{
struct Node* newnode = (struct Node*)malloc(sizeof(struct Node));
scanf("%d", &newnode->val);
newnode->next = NULL;
temp->next = newnode;
temp = newnode;
Numbers->tail = newnode;
}
Print(Numbers);
Print(Numbers);
return 0;
}
When I first print the list it prints out correctly but then the second time it prints nothing and program crashes. I dont know why the list is getting destroyed, even though I am using temp node to print it. Should I change the print function or the problem is something else ?
Your problem come from the line:
print->next = print->next->next;
This line change the pointer of head->next. When you run it the first time the pointer of head->next is changed to every node and at the end is set to NULL.
To fix it just change it to:
print = print->next;
Then you can print you linked list correctly without changing the original linked list.
You probably want to change print->next = print->next->next; to print = print->next;.

Linked list not showing proper data

I'm learning on linked list so decided to do some exercise here I'm trying to show the data entered in the list. I've also include a comment for my understanding on the line
typedef struct node {
int num;
struct node *nextptr;
}Node;
Node *stnode;
void createNodeList(int n);
void displayList();
This are my created Node
void createNodeList(int n) {
Node *tmp;
int num = 1;
//allocate memory address to stnode
Node *stnode = (Node *)malloc(sizeof(Node));
if (stnode == NULL) {
printf("Memory error");
}
else {
printf("Input data for node 1:");
scanf("%d", &num);
//declare the stnode num field in struct as user input
stnode->num = num;
//declare the stnode address of the next node NULL (to be the last node)
stnode->nextptr = NULL;
//define the node name as tmp
tmp = stnode;
for (int i = 2; i <= n; i++) {
//allocate node to fnNode
Node *fnNode = (Node *)malloc(sizeof(Node));
if (fnNode == NULL) {
printf("Memory can not be allocated");
break;
}
else {
printf("Input data for node %d: ", i);
scanf("%d", &num);
//declare the node name fnNode num to store user input
fnNode->num = num;
//link the fnNode of nextptr to address null
fnNode->nextptr = NULL;
//link tmp node to fnNode
tmp->nextptr = fnNode;
tmp = tmp->nextptr;
}
}
}
}
This is to display them
void displayList() {
Node *tmp;
if (stnode == NULL) {
printf("List is empty");
}
else {
tmp = stnode;
while (tmp != NULL) {
printf("Data = %d\n", tmp->num);
tmp = tmp->nextptr;
}
}
}
After I've input 3 data, it should show the data I've input.
But it show "List is empty"
Thank you =)
Node *stnode = (Node *)malloc(sizeof(Node));
By this you are shadowing the global variable. That's why you retain no changes in the global variable. All you have done is used a local variable with same name as that of the global variable stNode.
That line should be
stnode = (Node *)malloc(sizeof(Node));
Don't cast the return value of malloc. It should be
stnode = malloc(sizeof(Node));
Or even more clearly
stnode = malloc(sizeof *stnode);
If you compile this program with -Wshadow option then you will
get warning regarding this shadowing. Enable all compiler warnings. It
helps.

How to implement a [copy array to linked list] function?

What this supposed to do is:
Create an array with 4 elements.
Print these 4 elements.
Copy array elements to a created linked list in copy fucntion.
Print linked list with print and traverse fuction.
I tried this and it compiles, but crashes after printing the array.
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
#define ELEMENTS 4
struct node {
int data;
struct node *next;
};
struct node *head;
void insert(int x) {
struct node *temp = malloc(sizeof(struct node));
temp->data = x;
temp->next = NULL;
if (head != NULL)
temp->next = head;
head = temp;
}
void copy(struct node *head, int array[ELEMENTS], int n) {
//copying array elements and create linked list
struct node *temp = malloc(sizeof(struct node));
temp->data = array[0];
temp->next = NULL;
head = temp;
int i;
for (i = 1; i < n; i++) {
struct node *temp2 = malloc(sizeof(struct node));
temp->next = temp2;
temp2->data = array[i];
temp2->next = NULL;
temp = temp2;
}
}
void printlist() {
struct node*temp = head;
printf("List is : ");
while (temp->next != NULL) {
printf(" %d ", temp->data);
temp = temp->next;
}
printf("\n");
}
int main() {
int *array = (int*)calloc(ELEMENTS , sizeof(int));
int i = 0;
for (i = 0; i < ELEMENTS; i++) {
printf("arrays = [%d] ", i);
scanf("%d", &array[i]);
}
for (i = 0; i < ELEMENTS; i++)
printf("array [%d] = %d \n", i, array[i]);
copy(head, array[ELEMENTS], ELEMENTS);
printlist();
getchar();
return(0);
}
How to fix it?
You dont need to pass head to the copy function because it is global and when you do you create a local pointer named head which gets destroyed as soon as function is over.
So copy should look like this
void copy(int array[ELEMENTS],int n) //copying array elements and create linked list
{
struct node*temp = malloc(sizeof(struct node));
temp->data=array[0];
temp->next=NULL;
head =temp;
int i;
for(i=1;i<n;i++)
{
struct node*temp2= malloc(sizeof(struct node));
temp->next= temp2;
temp2->data = array[i];
temp2->next = NULL;
temp=temp2;
}
}
Also while printing change while to
while(temp!=NULL)
{
printf(" %d ",temp->data);
temp=temp->next;
}
When you call the function copy, you are passing "array[ELEMENTS]" as an argument, but you want to pass only "array". What you're passing is value after your array, which the copy function is trying to interpret as an address of an array it's actaully expecting.
Note that accessing a value that is not yours like this results in undefined behaviour and can actually make the system kill your application. But what probably happened after is there will be a 0 in the memory, which gets passed to the copy function and it then tries to access values at memory 0x0 to 0xF, which almost always results in segmentation fault, which as you experienced first hand, causes the program to stop working.
Bottom line, delete [ELEMENTS] at the line where you call the copy function and I believe the program should start working. I implore you though to do further research on pointers and passing them as function parameters.
(And since I cannot comment yet I will just put this in here, as Sniper stated, you don't have to pass reference to global variable, but he is wrong about the structure being destroyed at the end of the function. That would have been true, if it was created at stack, but you are allocating space for it at heap, which means it will stay there until you either free() it or the program ends.)
I have simple dimple answer:
#include<stdio.h>
#include<stdlib.h>
struct Node{
int current;
struct Node *next;
};
struct LinkedList{
struct Node *head;
};
int main(){
int i, data[5] = {10, 20, 30, 40, 50};
struct Node *node = malloc(sizeof(struct Node));
struct LinkedList *llist = malloc(sizeof(struct LinkedList));
node->current = data[0];
node->next = NULL;
llist-> head = node;
for(i = 1; i <= sizeof(data) / sizeof(data[0]) - 1; i++){
struct Node *new_node = malloc(sizeof(struct Node));
node->next = new_node;
new_node->current = data[i];
new_node->next = NULL;
node = new_node;
}
node = llist->head;
printf("llist: ");
while(node != NULL){
printf("%d->", node->current);
node = node->next;
}
return 0;
}

Resources