Insert an element in end of a singly Linked List - c

I have been trying to fix this code since morning but could get it done. So, finally i need some help in figuring out the error. The code compiles with no error but when i run it from terminal i get an error saying "segmetation error: 11"
#include <stdio.h>
#include <stdlib.h>
struct Node{
int data;
struct Node *next;
};
struct Node *head;
void Insert(int data);
void Print();
int main()
{
head = NULL; //list is empty
Insert(3);
Insert(5);
Insert(2);
Insert(8);
Print();
return 0;
}
void Insert(int data)
{
struct Node *temp = malloc(sizeof(struct Node));
temp->data = data;
temp->next = NULL;
struct Node *temp1 = head;
while(temp1 != NULL)
{
temp1= temp1->next;
}
temp1->next = temp;
}
void Print()
{
struct Node *temp =head;
while(temp != NULL)
{
temp = temp->next;
printf("%d", temp->data);
}
}

You never set head to anything other than NULL.
(Even if you fix the above) temp1 is guaranteed to be NULL by the time you get to temp1->next = temp;.
P.S. I don't think it's such a great practice to call you variables temp, temp1 etc. From those names it is impossible to tell what their supposed function is.

Usually single linked lists have an inserting operation that inserts data at the beginning of the list. Nevertheless your function insert can look the following way
void Insert( int data )
{
struct Node *temp = malloc(sizeof( struct Node ) );
temp->data = data;
temp->next = NULL;
if ( head == NULL )
{
head = temp;
}
else
{
struct Node *current = head;
while ( current->next != NULL ) current = current->next;
current->next = temp;
}
}
It would be better if you check in the function whether the node was allocated.
Function Print also is wrong. It can look like
void Print( void )
{
for ( struct Node *current = head; current != NULL; current = current->next )
{
printf( "%d ", current->data );
}
}

You are writing
while(temp1 != NULL)
Make it like this
while(temp1->next != NULL)
Here, temp1 points to null at the end of loop, and you are trying to add node after null i.e.
null->next =temp;
which must be throwing error.

struct Node *curr;
void Insert(int data){
struct Node *temp = malloc(sizeof(struct Node));
temp->data = data;
temp->next =NULL;
if(head == NULL)
curr = head = temp;
else
curr = curr->next = temp;
}
void Print(){
struct Node *temp =head;
while(temp != NULL){
printf("%d ", temp->data);
temp=temp->next;
}
}

Related

What is the logical error in my attempt to implement the insertion of nodes in the linked list?

I'm unable to get an output for inserting nodes at the beginning, end, and after a given node. I'm not very sure if there is anything that I missed out in the main(). I'm unable to point out my logical error in the program
`
#include<stdio.h>
#include<stdlib.h>
struct node{
int data;
struct node *next;
};
//Inserts at the begining
void push(struct node **head, int x){
struct node *newnode = (struct node *)malloc(sizeof(struct node));
newnode->data = x;
*head = newnode;
newnode->next = (*head);
*head = newnode;
}
//Insert at the last
void append(struct node **head, int x){
struct node *temp;
struct node* newnode = (struct node*)malloc(sizeof(struct node));
newnode->data = x;
newnode->next = 0;
if(*head == 0){
*head = newnode;
}
temp = *head;
while(temp->next != 0){
temp = temp->next;
}
temp->next = newnode;
}
//inserting at a given node
void insertAfter(struct node* temp, int x){
if(temp == NULL){
printf("previous node cannot be NULL");
}
struct node* newnode = (struct node*)malloc(sizeof(struct node));
newnode->data = x;
newnode->next = temp->next;
temp->next = newnode;
}
void printList(struct node *temp){
while(temp->next != NULL){
printf("%d",temp->data);
}
temp = temp->next;
}
int main(){
struct node *head = NULL;
append(&head,6);
push(&head, 7);
push(&head, 1);
append(&head, 4);
insertAfter(head->next, 8);
printf("Created linked list is:\n");
printList(head);
return 0;
}
`
The output is 1 7 8 6 4
But I'm getting no output and no errors as well
Within the function print_list there can be an infinite loop because this statement
temp = temp->next;
is placed after the while loop
void printList(struct node *temp){
while(temp->next != NULL){
printf("%d",temp->data);
}
temp = temp->next;
}
The function can look for example the following way
void printList( const struct node *head )
{
for ( ; head != NULL; head = head->next )
printf( "%d -> ", head->data );
}
puts( "null" );
}
Pay attention to that within the function push this statement
*head = newnode;
is present twice.
Also the functions are unsafe because there is no check whether memory was allocated successfully within the functions.
For example the function append could be declared and defined the following way
//Insert at the last
int append( struct node **head, int x )
{
struct node *newnode = malloc( sizeof( *newnode ) );
int success = newnode != NULL;
if ( success )
{
newnode->data = x;
newnode->next = NULL;
while ( *head != NULL ) head = &( *head )->next;
*head = newnode;
}
return success;
}

getting segmentation error (core dumped) in linked list

I have looked at my code several times but couldn't find the problem. please tell me what I need to replace to get my code working.
#include <stdio.h>
#include <stdlib.h>
#include <conio.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;
if (head == NULL)
{
temp->next = head;
head = temp;
return;
}
struct node *temp1 = head;
while(temp1 != NULL)
{
temp1 = temp1->next;
}
temp1->next = temp;
}
void display()
{
struct node *temp = head;
if (head == NULL)
{
printf("list is empty");
return;
}
else{
while(temp!=NULL)
{
printf("%d ", temp->data);
temp = temp->next;
}
}
}
int main()
{
head = NULL;
insert(3);
insert(5);
insert(6);
display();
}
The problem is in this code:
struct node *temp1=head;
while(temp1!=NULL)
{
temp1=temp1->next;
}
temp1->next=temp;
... the while loop won't end until temp1 is NULL, so after the loop ends, it is guaranteed that temp1 is a NULL pointer ... and then you dereference that NULL pointer (via temp1->next), which causes a crash. Probably what you want to do instead is while(temp1->next != NULL) {...}
while(temp1!=NULL)
{
temp1=temp1->next;
}
temp1->next=temp;
The only way out of this loop is for temp1 to be NULL. Then the next line attempts to used temp1 as a pointer. This is likely causing your issue. You need to instead check if the next is NULL and break leaving temp1 as the last in the list not it's next.
Pro tip for linked lists like this, they are a lot easier to modify with double pointers. Example code:
void append(struct node **list, int a) {
// skip to the end of the list:
while (*list != NULL) {
list = &(*list)->next;
}
*list = malloc(sizeof(struct node));
(*list)->data = a;
(*list)->next = NULL;
}
void display(struct node *list) {
while (list) {
printf("%d\n", list->data);
list = list->next;
}
}
void remove(struct node **list, int index) {
while (*list) {
if (--index == 0) {
struct node *temp = *list;
*list = temp->next;
free(temp);
break;
}
}
}
int main() {
struct list *mylist;
append(&mylist, 3);
append(&mylist, 4);
append(&mylist, 5);
display(mylist); // prints 3 4 5
remove(&mylist, 1);
display(mylist); // prints 3 5
remove(&mylist, 0);
remove(&mylist, 0);
// mylist is NULL again, all memory free'd
}
Note that this code needs no special cases for "is the list empty?", which makes it less complex than yours.

Linked List elements not getting displayed

This is my program in C which always inserts into a linked list at the end. But when I try to print the list elements, nothing is displayed. Here is the code :
#include<stdio.h>
#include<stdlib.h>
struct Node
{
int data;
struct Node *next;
};
void insert(struct Node *, int);
int main(void)
{
struct Node *head = NULL, *current;
int n, i, x, data;
scanf("%d", &n);
for(i = 0; i < n; i++)
{
scanf("%d", &data);
insert(head, data);
}
current = head;
while(current != NULL)
{
printf("%d ", current->data);
current = current->next;
}
}
void insert(struct Node *head, int data)
{
struct Node *newnode, *current = head;
newnode = (struct Node *)malloc(sizeof(struct Node));
newnode->data = data;
newnode->next = NULL;
if(head == NULL)
{
head = newnode;
}
else
{
while(current->next != NULL)
{
current = current->next;
}
current->next = newnode;
}
}
I cannot understand what might be the issue. Please help.
Your insert cannot modify head. Change it to
void insert(struct Node **head, int data)
and change it by
*head = newnode;
and call it like this
insert(&head, data);
Here, while you are passing the head pointer to your insert() function, it is not being updated in your main() function.
So, either declare your head pointer as global or return your head pointer and update it in your main() function.
In the below code I had taken the head pointer as global and removed the head pointer as your parameter from the insert() function.
Here is the code :-
#include<stdio.h>
#include<stdlib.h>
struct Node
{
int data;
struct Node *next;
};
struct Node *head=NULL;
void insert(int);
int main(void)
{
struct Node *current;
int n, i, x, data;
clrscr();
scanf("%d", &n);
for(i = 0; i < n; i++)
{
scanf("%d", &data);
insert(data);
}
current = head;
while(current != NULL)
{
printf("%d \n", current->data);
current = current->next;
}
getch();
return 0;
}
void insert(int data)
{
struct Node *newnode, *current = head;
newnode = (struct Node *)malloc(sizeof(struct Node));
newnode->data = data;
newnode->next = NULL;
if(head == NULL)
{
head = newnode;
}
else
{
while(current->next != NULL)
{
current = current->next;
}
current->next = newnode;
}
}
You need to pass the reference of the head pointer, then only the changes made to it will be visible.
You must declare your function like
void insert(struct Node **, int);
and also call it like
insert(&head, data);
also, make changes to function definition
void insert(struct Node **head, int data)
{
struct Node *newnode, *current = *head;
newnode = (struct Node *)malloc(sizeof(struct Node));
newnode->data = data;
newnode->next = NULL;
if(*head == NULL)
{
*head = newnode;
}
else
{
while(current->next != NULL)
{
current = current->next;
}
current->next = newnode;
}
}
You need to pass the head by reference as you are making changes to it that should be visible.
insert(head, data);
should become
insert(&head, data);
Also the function signature will change.
void insert(struct Node *head, int data)
should become
void insert(struct Node **head, int data)
Also make appropriate changes in the function.
Like,
current = *head;
Because you are passing the pointer by value. The function operates on a copy of the pointer, and never modifies the original.
Either pass a pointer to the pointer (i.e. a struct head **), or instead have the function return the pointer.
You can try running the following code which will give the output as null
printf("%s",head);
while(current != NULL)
{
printf("%d", current->data);
current = current->next;
}

Linked list implementation in C(printing only last two nodes)

#include <stdlib.h>
#include <stdio.h>
struct node {
int data;
struct node *next;
};
void addLast(struct node **head, int value);
void printAll(struct node *head);
struct node *head1 = NULL;
int main() {
addLast(&head1, 10);
addLast(&head1, 20);
addLast(&head1, 30);
addLast(&head1, 40);
printAll(head1);
return 0;
}
void addLast(struct node **head, int value) {
struct node *newNode = (struct node*)malloc(sizeof(struct node));
newNode->data = value;
if (*head == NULL) {
*head = newNode;
(*head)->next = NULL;
} else {
struct node **temp = head;
while ((*temp)->next != NULL) {
*temp = (*temp)->next;
}
(*temp)->next = newNode;
newNode->next = NULL;
}
}
void printAll(struct node *head) {
struct node *temp = head;
while (temp != NULL) {
printf("%d->", temp->data);
temp = temp->next;
}
printf("\n");
}
addLast() will append the new node at the end of the list, with printAll(), I am printing entire list.
Every time when I am printing the list, I can only see the last two nodes.
Can anyone please help, why loop is not iterating over entire list ?
The function addLast is too complicated and as result is wrong due to this statement
*temp = (*temp)->next;
in the while loop. It always changes the head node.
Define the function the following way
int addLast( struct node **head, int value )
{
struct node *newNode = malloc( sizeof( struct node ) );
int success = newNode != NULL;
if ( success )
{
newNode->data = value;
newNode->next = NULL:
while( *head ) head = &( *head )->next;
*head = newNode;
}
return success;
}
Take into account that there is no need to declare the variable head1 as global. It is better to declare it inside the function main.
Also all the allocated memory should be freed before exiting the program.

Implementing Simple Linked List

Hi I wish to implement a simple linked list and all the values to the end of the list. As simple as that but I am not able to do so. Can you please tell me where I am doing it wrong ? Initially I am declaring a pointer and assigning NULL value to it. Later in each iteration I am allocating memory to the pointer that was initially NULL.
#include <stdio.h>
#include <malloc.h>
struct node{
int a;
struct node* next;
};
struct node* insert(struct node* start,int value);
void print(struct node* head);
int main()
{
int a;
struct node* head = NULL;
while(scanf("%d",&a) != EOF)//taking input
{
head = insert(head,a);
print(head);
}
return 0;
}
struct node* insert(struct node* start,int value)
{
struct node* head = start;
while(start != NULL)
{
start = start->next;//getting upto the end of the linked list
}
start = (struct node*)malloc(sizeof(struct node));//allocating memory at the end
start->a = value;
start->next = NULL;
if(head == NULL)
{
return start;//for the base case when list is initally empty
}
return head;
}
void print(struct node* head)
{
while(head != NULL)
{
printf("%d\n",head->a);
head = head->next;
}
return;
}
You're losing your linkage between your tail and your new node, try this instead
struct node* insert(struct node* head,int value)
{
struct node* tail = head;
while(tail != NULL && tail->next != NULL)
{
tail= tail->next;//getting upto the end of the linked list
}
struct node* start = (struct node*)malloc(sizeof(struct node));//allocating memory at the end
start->a = value;
start->next = NULL;
if(head == NULL)
{
return start;//for the base case when list is initally empty
}
else
{
tail->next = start;
}
return head;
}
struct node* insert(struct node* start,int value){
struct node* head = start;
struct node* np = (struct node*)malloc(sizeof(struct node));
np->a = value;
np->next = NULL;
if(head == NULL)
return np;
while(start->next != NULL){
start = start->next;
}
start->next = np;
return head;
}
What makes the approach I am using buggy ?
nodeX
|
+a
|
+next(address to OtherX)
nodeX.next = new_node;//update link(case of OK)
tempPointer = nodeX.next;//address to OtherX set to tempPointer
tempPointer = new_node;//contents of tempPointer changed, but orignal (nodeX.next not change)

Resources