I'm trying to create a simple linked list and insert a node at the end of the list. I'm getting a segmentation fault.
#include <stdio.h>
#include <stdlib.h>
struct node{
int data;
struct node *link;
};
void create(struct node *head){
struct node* second = NULL;
struct node* last = NULL;
second = (struct node*)malloc(sizeof(struct node));
last = (struct node*)malloc(sizeof(struct node));
second -> data = 2;
last -> data = 3;
head -> link = second;
second -> link = last;
last -> link = NULL;
}
void insert_ending(struct node *head){
struct node* temp = NULL;
struct node* temp1 = NULL;
temp1 = (struct node*)malloc(sizeof(struct node));
temp1 -> data = 5;
temp1 -> link = NULL;
temp = head;
while(temp != NULL){
temp = temp -> link;
}temp -> link = temp1;
}
void PrintList(struct node *head){
while( head != NULL ){
printf(" %d -->", head -> data);
head = head -> link;
}
printf("\n");
}
int main(){
struct node* head = NULL;
head = (struct node*)malloc(sizeof(struct node));
head -> data = 1;
head -> link = NULL;
create(head);
PrintList(head);
insert_ending(head);
PrintList(head);
return 0;
}
I'm getting a segmentation fault. The output is as follows.
1 --> 2 --> 3 -->
Segmentation fault (core dumped)
in your insert function you need to change to :
temp = head;
while(temp -> link != NULL){
temp = temp -> link;
}
temp -> link = temp1;
the reason is that when you loop with while until temp == null, you can't afterward do: temp -> link because temp is allready null.
In the function 'insert_ending' in the while loop you want to change the
condition from:
while ( temp != NULL )
to:
while ( temp->link != NULL )
because now once the loop is finished, temp is NULL and then you try to dereference it (a NULL pointer) and get an error.
Related
I got this code on codeblocks 13.12 in lubuntu 16.04
The program is running but the problem is that the first insertion is duplicated that is,
lets say i first insert integer "4" to the linked list. But i get the output as:
4 ,4 ,
#include <stdio.h>
#include <stdlib.h>
struct node {
int data;
struct node* next;
};
struct node* head = NULL;
void Insert(int c)
{
if(head == NULL) {
struct node* temp = malloc(sizeof(struct node));
temp -> data = c;
temp -> next = NULL;
head = temp;
}
struct node* temp = malloc(sizeof(struct node));
temp -> data = c;
temp -> next = NULL;
struct node* temp1 = head;
while (temp1->next != NULL) {
temp1 = temp1->next;
}
temp1 -> next = temp;
}
void print() {
struct node* temp = head;
printf("list is: \n");
while (temp != NULL) {
printf( "%d ,",temp->data);
temp = temp->next;
}
}
int main () {
printf("How Many Numbers?\n");
int a ,b ,c;
scanf("%d" , &b);
for(a = 0;a<b;a++) {
printf("Enter the numbers \n");
scanf("%d",&c);
Insert(c);
print();
}
return 0;
}
the problem is that the first insertion is duplicated
Reason:
You've mentioned if(head==NULL) correctly to check whether inserted node is first node or not but after this you did not mention else to restrict compiler.
So the compiler compiles both the if block and the code following it
So another node gets created after head with the same value c
that's the reason when you insert c=4, you get 4,4, as output
Solution
Try using your insert() with an else condition as
void Insert(int c)
{
if(head == NULL)
{
struct node* temp = malloc(sizeof(struct node));
temp -> data = c;
temp -> next = NULL;
head = temp;
}
else
{
struct node* temp = malloc(sizeof(struct node));
temp -> data = c;
temp -> next = NULL;
struct node* temp1 = head;
while (temp1->next!= NULL)
temp1 = temp1->next;
temp1 -> next = temp;
}
}
suggestion : you've mentioned this twice in you insert() function
struct node* temp = malloc(sizeof(struct node));
temp -> data = c;
temp -> next = NULL;
just allocate temp once and then insert it at approprite position using if-else conditions. This reduces the number of lines of code too. do it this way:
void Insert(int c)
{
struct node* temp = malloc(sizeof(struct node));
temp -> data = c;
temp -> next = NULL;
if(head == NULL)
{
head = temp;
}
else
{
struct node* temp1 = head;
while (temp1->next!= NULL)
temp1 = temp1->next;
temp1 -> next = temp;
}
}
That is because the Insert function "falls through" after initialising the first item, and inserts it again. Add return at the end of the code block.
void Insert(int c)
{
if(head == NULL) {
struct node* temp = malloc(sizeof(struct node));
temp -> data = c;
temp -> next = NULL;
head = temp;
return; //<-- add this line
}
...
#include<stdio.h>
#include<stdlib.h>
typedef struct Node{
int val;
struct Node* next;
} Node;
void add_at_end(Node* head, int val){
Node* newNode = malloc(sizeof(Node));
newNode -> next = NULL;
Node* temp = head;
if(head -> next == NULL){
head ->val = val;
head -> next = newNode;
}
else{
while(temp -> next != NULL){
temp = temp -> next;
}
temp -> next = newNode;
temp -> val = val;
}
}
void display(Node* l){
while(l->next != NULL){
printf("%d -->", l->val);
l = l->next;
}
printf("End\n");
}
As I said in the question, I'm creating a useless node at the end just to specify NULL. How can I remove that feature? I know I'm doing something wrong in the add_at_end function but I'm not able to rectify it. Help would be appreciated. Thanks
EDIT:
#include<stdio.h>
#include<stdlib.h>
typedef struct Node{
int val;
struct Node* next;
} Node;
typedef struct List{
Node* head;
} List;
void add_at_end(List* l, int val){
Node* newNode = malloc(sizeof(Node));
newNode -> next = NULL;
newNode -> val = val;
Node* temp = l->head;
if(temp == NULL){
l->head = newNode;
}
else{
while(temp->next != NULL){
temp = temp -> next;
}
temp -> next = newNode;
}
}
void display(List* l){
Node* t = l -> head;
while(1){
printf("%d\n", t->val);
if(t->next == NULL) break;
t = t->next;
}
}
int main(){
List l;
l.head = NULL;
add_at_end(&l, 10);
add_at_end(&l, 20);
add_at_end(&l, 30);
display(&l);
return 0;
}
This is my final code.
I need help adding nodes to the middle of the list. How can I do that?
Your node usage is all confused. When you create a new node the value should be stored into that node and the node linked into the list. Instead what you are doing is trying to add the value into the last node and then linking in a dummy node. It's a bit convoluted so I'm not sure I've explained what you have done clearly. Here is what add_to_end should be more like:
add_to_end (Node** head, int val)
{
Node* temp;
Node* newNode = malloc(sizeof(Node));
if (!newNode) {
/* Error */
}
newNode->val = val;
newNode->next = NULL;
if (!*head) {
/* empty list. Just make new node the head */
*head = newNode;
} else {
/* Find the end of the list */
temp = *head;
while (temp->next) {
temp = temp->next;
}
/* temp is now the last node. Chain new node after it */
temp->next = newNode;
}
}
Instead of a null node, you can represent the end of the list with a value of NULL, i.e. with a null pointer. The list is empty when head is NULL and the last node has node->next == NULL.
For this to work, you must be able to update the head when you add a node, because after inserting the frst node, the head will no longer be NULL. (The same goes for inserting at the front or deleting the first node.)
This chan be achieved by passing a pointer to a node pointer:
void add_at_end(Node **head, int val)
{
Node* newNode = malloc(sizeof *newNode);
newNode->next = NULL;
newNode->val = val;
while (*head) {
head = &(*head)->next;
}
*head = newNode;
}
Then you call add_at_and like this:
Node *head = NULL;
add_at_end(&head, 1);
add_at_end(&head, 2);
add_at_end(&head, 3);
It is important that head is initialised to NULL. More generally, all your pointers should either be NULL or point to valid nodes.
#include<stdio.h>
#include<stdlib.h>
typedef struct Node{
int val;
struct Node* next;
} Node;
void add_at_end(Node* head, int val){
Node* newNode = (Node *)malloc(sizeof(Node));
newNode -> next = NULL;
if(head == NULL)
{
head = new_node;
head->val = val;
}
if(head -> next == NULL)
{
new_node ->val = val;
head -> next = newNode;
}
else{
Node *temp = head;
while(temp -> next != NULL){
temp = temp -> next;
}
temp -> next = newNode;
temp -> val = val;
}
}
void display(Node* l){
while(l->next != NULL){
printf("%d -->", l->val);
l = l->next;
}
printf("End\n");
}
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.
#include <stdio.h>
#include <conio.h>
struct node
{
int data;
struct node* next;
};
int main()
{
struct node* head = NULL;
struct node* second = NULL;
struct node* third = NULL;
head = (struct node*)malloc(sizeof(struct node));
second = (struct node*)malloc(sizeof(struct node));
third = (struct node*)malloc(sizeof(struct node));
head->data = 1;
head->next = second;
second->data = 2;
second->next = third;
third->data = 3;
third->next = NULL;
struct node* new1;
struct node* temp1;
temp1 = head;
while(temp1->next != NULL)
{
temp1 = temp1->next;
}
new1 = (struct node*)malloc(sizeof(struct node));
temp1->next = new1;
new1->data = 5;
new1->next = NULL;
while(temp1 != NULL)
{
printf("%d ",temp1->data);
temp1 = temp1->next;
}
return 0;
}
This is the program for inserting a node at the end of linked list. The expected output is = 1 2 3 5, 5 is the new node's value here. But the current output is = 3 5. I don't know where am I wrong. Any answer will be appreciated.
while(temp1->next != NULL)
{
temp1 = temp1->next;
}
After this loop your temp1 is at the end of the list and you are adding a node at the end of the list.
Now you are trying to print from temp1 obviously you will get only 2 nodes new one and the one before it.
If you want the whole list print from head.
Just before printing after adding your new node. Point temp1 to head.
temp1 = head;
while(temp1 != NULL)
{
printf("%d ",temp1->data);
temp1 = temp1->next;
}
One thing to remember when using something like you did to get to the end of the list: If you just say third->next = first, then it will go on forever. This is something to watch out for, and also something you may want to play with. Maybe consider adding a list_size integer somewhere so that infinite looping does not happen.
My program keeps on crashing. I think there's a problem in my logic. Please help! Thanks!
struct node{
int data;
struct node *prev,*next;
} *head = NULL;
void insert(){
struct node* temp = (struct node*) malloc (sizeof (struct node*));
int value;
printf("Enter an element");
scanf("%d",&value);
temp -> data = value;
temp -> next = NULL;
temp -> prev = NULL;
if(value < head -> data || head == NULL){
temp -> next = head -> next;
head = temp;
return;
}
while(head->next != NULL && value > head -> next -> data)
head = head -> next;
temp -> next = head ->next->prev;
head -> next = temp -> prev;
while (head -> prev != NULL)
head = head -> prev;
}
Try this:
#include <stdio.h>
#include <stdlib.h>
struct node{
int data;
struct node *prev,*next;
} *head = 0;
void insert(int value){
struct node* temp = (struct node*) malloc (sizeof (struct node));
//int value;
//printf("Enter an element");
//scanf("%d",&value);
temp -> data = value;
temp -> next = 0;
temp -> prev = 0;
if(head == 0) {
// no head, make temp the head
head = temp;
} else if(value > head->data) {
// put temp in front of the head
temp->next = head;
head->prev = temp;
head = temp;
} else {
// put temp after the head
struct node *this = head;
struct node *prev = 0;
while(this && this->data > value) {
prev = this;
this = this->next;
}
temp->next = this;
temp->prev = prev;
prev->next = temp;
if(this) {
this->prev = temp;
}
}
}
int main() {
insert(1);
insert(3);
insert(4);
struct node *t = 0;
for(t = head; t; t = t->next) {
printf("%d\n", t->data);
}
}
This one compiles and sorts in descending value. Note I commented out your scanf
and made insert take a parameter.
the space you malloc is not enough.
change
struct node* temp = (struct node*) malloc (sizeof (struct node*));
to
struct node* temp = (struct node*) malloc (sizeof (struct node));
As a start, think about these two lines and what happens if head == NULL:
if(value < head->data || head == NULL){
temp->next = head->next;
Specifically what is head->next?
There are two core problems I see.
You are not allocating sufficient space for a node struct. sizeof(struct node *) returns the size of a node pointer, not a node. This:
struct node* temp = (struct node*) malloc (sizeof (struct node*));`
... should be this:
struct node* temp = (struct node*) malloc (sizeof (struct node));
Be careful with pointers:
if (value < head -> data || head == NULL)
... what is the value of head->data if you haven't initialized head? (e.g. it is still NULL). Your program will fetch data from address NULL with an offset for field data. Address NULL is not valid / is part of protected memory space, your OS won't like this :).
You should first check if head is NULL. If it is, then you can't reference fields of head as they are invalid (in any situation). Be careful with multi-part conditional expressions to check for struct pointer NULL presence prior to subsequent parts that reference struct fields, also.