Segmentation fault in C while implementing deque - c

I am trying to implement a deque in C. I am learning C, so the error might seem very trivial. Here's the entire program
#include <stdio.h>
#include <stdlib.h>
typedef struct node{
int data;
struct node *prev;
struct node *next;
}Node;
Node *getNode(int data){
Node *temp = (Node *)malloc(sizeof(Node));
temp -> next = temp -> prev = NULL;
temp -> data = data;
return temp;
}
void push_right(Node **head, Node **tail, int data){
Node *newNode = getNode(data);
Node *temp = (*head);
if (temp == NULL){
*head = newNode;
}
else{
while(temp -> next != NULL){
temp = temp -> next;
}
temp -> next = newNode;
newNode -> prev = temp;
*tail = newNode;
}
}
void push_left(Node **head, Node **tail, int data){
Node *newNode = getNode(data);
Node *temp = (*head);
if (temp == NULL){
*head = newNode;
}
else{
newNode -> next = temp;
newNode -> prev = NULL;
(*head) = newNode;
}
}
void remove_right(Node **head, Node **tail, int *val){
Node *temp = (*tail);
if (temp == NULL)
{
printf("Cannot be removed doesn't point to anything\n");
return;
}
else{
*val = temp -> data;
temp = temp -> prev;
(*tail) = temp;
}
free(temp);
}
void remove_left(Node **head, Node **tail, int *val){
Node *temp = (*head);
if (temp == NULL)
{
printf("Cannot be removed doesn't point to anything\n");
return;
}
else{
*val = temp -> data;
temp = temp -> next;
(*tail) = temp;
}
free(temp);
}
void print_all(Node *head){
Node *temp = head;
printf("\n");
while(temp != NULL){
printf("%d\n",temp->data);
temp = temp -> next;
}
}
int main(int argc, char const *argv[])
{
int *val = NULL;
Node *head = NULL;
Node *tail = NULL;
for (int i = 0; i < 10; ++i){
push_right(&head, &tail,i);
push_left(&head, &tail,i);
}
remove_left(&head, &tail, val);
print_all(head);
return 0;
}
The problem seems to arise when remove_left() is called. I have spend a significant amount of time to understand where the problem is coming from but nothing seems to work. Please help.
This is the output on the Terminal screen.
lib2s-iMac:queue admin$ ./a.out
Segmentation fault: 11

Problem is here :
*val = temp -> data;
Val is NULL, so trying to dereference it will result in segmentation fault.
If you change val type to an int instead of a pointer to an int. And then call remove_left like this :
int main(int argc, char const *argv[])
{ int val = 0;
Node *head = NULL;
Node *tail = NULL;
for (int i = 0; i < 10; ++i){
push_right(&head, &tail,i);
push_left(&head, &tail,i);
}
remove_left(&head, &tail, &val);
print_all(head);
return 0;
}
This should work.

In your program have 3 main mistakes .
At int *val = NULL; Here it should be int val not int *val.
At function remove_left() . Here You should edit (*head) not (*tail).Also pointer (next,perv) are not managed properly.
Same in the case of remove_right(). Mistakes in managing pointers.
Modified Functions :-
void remove_right(Node **head, Node **tail, int *val) // modified This function.
{
Node *temp = (*tail);
if (temp == NULL)
{
printf("Cannot be removed doesn't point to anything\n");
return;
}
else
{
*val = temp->data;
temp->prev->next = NULL;
(*tail) = temp->prev;
}
free(temp);
}
void remove_left(Node **head, Node **tail, int *val) // modified This function.
{
Node *temp = (*head);
if (temp == NULL)
{
printf("Cannot be removed doesn't point to anything\n");
return;
}
else
{
*val = temp->data;
temp->next->prev = NULL;
(*head) = temp->next;
}
free(temp);
}
Modified main() :-
int main(int argc, char const *argv[])
{
int val = -1; // Modified here
Node *head = NULL;
Node *tail = NULL;
for (int i = 0; i < 10; ++i)
{
push_right(&head, &tail, i);
push_left(&head, &tail, i);
}
remove_left(&head, &tail, &val);
print_all(head);
return 0;
}
Complete code Online.
Output :-
8
7
6
5
4
3
2
1
0
0
1
2
3
4
5
6
7
8
9

Related

Reverse Every K Nodes

Every k nodes form a segment. If the last few nodes are less than K, then you can ignore them.
Write a reverseKnodes() which reserves every segment in the linked list.
The function prototype is given as follow: void reversekNodes(ListNode** head, int k);
Input format:
The 1st line is the k
The 2nd line is the data to create the linked list and ends with a non-digit symbol Example:
Input: 3 1 2 3 4 5 6 7 8 9 10 a
Output: 3 2 1 6 5 4 9 8 7 10
#include <stdio.h>
#include <stdlib.h>
struct _listNode
{
int item;
struct _listNode *next;
};
typedef struct _listNode ListNode;
void printList (ListNode * head);
void deleteList (ListNode ** ptrHead);
void reverseKNodes (ListNode ** head, int K);
int
main ()
{
ListNode *head = NULL, *temp;
int i = 0;
int K = 0;
scanf ("%d", &K);
while (scanf ("%d", &i))
{
if (head == NULL)
{
head = (ListNode *) malloc (sizeof (ListNode));
temp = head;
}
else
{
temp->next = (ListNode *) malloc (sizeof (ListNode));
temp = temp->next;
}
temp->item = i;
}
temp->next = NULL;
reverseKNodes (&head, K);
printList (head);
deleteList (&head);
return 0;
}
void
printList (ListNode * head)
{
while (head != NULL)
{
printf ("%d ", head->item);
head = head->next;
}
printf ("\n");
}
void
deleteList (ListNode ** ptrHead)
{
ListNode *cur = *ptrHead;
ListNode *temp;
while (cur != NULL)
{
temp = cur->next;
free (cur);
cur = temp;
}
*ptrHead = NULL;
}
void
reverseKNodes (ListNode ** head, int K)
{
struct _listNode *reverse (struct _listNode *head, int k){
if (!head)
return NULL;
struct _listNode* cur = head;
struct _listNode* next = NULL;
struct _listNode* prev = NULL;
int count = 0;
while (cur != NULL && count < K)
{
next = cur->next;
cur->next = prev;
prev = cur;
cur = next;
count++;
}
if (next != NULL)
head->next = reverse(next, K);
return prev;
}
}
I am not allowed to change anything else other than the void function for reverseKNodes and I know I have done it wrong but I dont know where I went wrong. Could someone help me please?
A few issues with nested functions ...
Nested functions aren't standard C.
Are of limited benefit.
They add extra overhead to invoke.
So [please] don't use them.
And, your usage of one is incorrect. In reverseKNodes, you define reverse but never call it. So, reverseKNodes is a no-op.
So, to fix, move reverse out of the body of reverseKNodes and place it above. Then, actually invoke it in reverseKNodes:
void
reverseKNodes(ListNode **head, int K)
{
*head = reverse(*head, K);
}
Here is the full refactored code. For aid in debug (e.g. with gdb), I added code to allow the program to take an input file as an argument.
#include <stdio.h>
#include <stdlib.h>
struct _listNode {
int item;
struct _listNode *next;
};
typedef struct _listNode ListNode;
void printList(ListNode *head);
void deleteList(ListNode **ptrHead);
void reverseKNodes(ListNode **head, int K);
int
main(int argc,char **argv)
{
ListNode *head = NULL, *temp;
int i = 0;
int K = 0;
--argc;
++argv;
FILE *xf;
do {
if (argc != 1) {
xf = stdin;
break;
}
xf = fopen(*argv,"r");
if (xf != NULL)
break;
perror(*argv);
exit(1);
} while (0);
fscanf(xf,"%d", &K);
while (fscanf(xf,"%d", &i)) {
if (head == NULL) {
head = (ListNode *) malloc(sizeof(ListNode));
temp = head;
}
else {
temp->next = (ListNode *) malloc(sizeof(ListNode));
temp = temp->next;
}
temp->item = i;
}
temp->next = NULL;
reverseKNodes(&head, K);
printList(head);
deleteList(&head);
return 0;
}
void
printList(ListNode *head)
{
while (head != NULL) {
printf("%d ", head->item);
head = head->next;
}
printf("\n");
}
void
deleteList(ListNode **ptrHead)
{
ListNode *cur = *ptrHead;
ListNode *temp;
while (cur != NULL) {
temp = cur->next;
free(cur);
cur = temp;
}
*ptrHead = NULL;
}
struct _listNode *
reverse(struct _listNode *head, int K)
{
if (! head)
return NULL;
struct _listNode *cur = head;
struct _listNode *next = NULL;
struct _listNode *prev = NULL;
int count = 0;
while (cur != NULL && count < K) {
next = cur->next;
cur->next = prev;
prev = cur;
cur = next;
count++;
}
if (next != NULL)
head->next = reverse(next, K);
return prev;
}
void
reverseKNodes(ListNode **head, int K)
{
*head = reverse(*head, K);
}
Here is the program output:
3 2 1 6 5 4 9 8 7 10

Garbage value for certain C functions

I'm learning C and I'm trying to make a program with multiple linked list operations all at once. They don't give me errors, but for the functions to delete a node at the end, and to insert at a certain position, I'm getting a garbage value at the beginning of the output.
Temporary program to implement just the insert function:
#include <stdio.h>
#include <stdlib.h>
struct node
{
int data;
struct node* next;
};
void inp(struct node **start, int ele)
{
struct node *NEW = (struct node*)malloc(sizeof(struct node));
NEW->data = ele;
struct node *ptr = *start;
while(ptr != NULL)
{
if(ptr->next == NULL)
{
ptr->next = NEW;
NEW->next = NULL;
break;
}
ptr = ptr->next;
}
}
void insert_pos(struct node **start, int ele, int pos)
{
struct node *ptr = *start;
for(int i = 1; i < pos; i++)
{
ptr = ptr->next;
}
struct node *NEW = (struct node*)malloc(sizeof(struct node));
NEW->data = ele;
NEW->next = ptr->next;
ptr->next = NEW;
}
void display(struct node* start)
{
struct node* ptr = start;
while(ptr != NULL)
{
printf("%d\n", ptr->data);
ptr = ptr->next;
}
}
int main()
{
struct node *a;
int m;
for(int i = 0; i < 10; i++)
{
scanf("%d", &m);
inp(&a, m);
}
insert_pos(&a, 594, 3);
printf("\n\n");
display(a);
}
Temporary program to delete at the end:
//Temporary
#include <stdio.h>
#include <stdlib.h>
struct node
{
int data;
struct node* next;
};
void inp(struct node **start, int ele)
{
struct node *NEW = (struct node*)malloc(sizeof(struct node));
NEW->data = ele;
struct node *ptr = *start;
while(ptr != NULL)
{
if(ptr->next == NULL)
{
ptr->next = NEW;
NEW->next = NULL;
break;
}
ptr = ptr->next;
}
}
void del_end(struct node **start)
{
struct node *ptr = *start;
while(ptr != NULL)
{
if(ptr->next->next == NULL)
{
ptr->next = NULL;
free(ptr->next->next);
break;
}
ptr = ptr->next;
}
}
void display(struct node* start)
{
struct node* ptr = start;
while(ptr != NULL)
{
printf("%d\n", ptr->data);
ptr = ptr->next;
}
}
int main()
{
struct node *a;
int m;
for(int i = 0; i < 10; i++)
{
scanf("%d", &m);
inp(&a, m);
}
del_end(&a);
printf("\n\n");
display(a);
}
Any idea how to fix it?
you can see that in here:
The inp problem:
struct node *a;
puts a garbage value in a that you don't handle and uses it like a node,
add =NULL to solve.
also, your function that deletes from the end has the following error:
struct node *ptr = *start;
while(ptr != NULL)
{
if(ptr->next->next == NULL)
{
ptr->nexStack Overflow for Teams – Collaborate and share knowledge with a private group.t = NULL;
free(ptr->next->next);
break;
}
ptr = ptr->next;
}
you are changing ptr-> next and than accessing ptr->next->next...

Need clear understanding why value isn't affected even if passed by reference? [duplicate]

This question already has an answer here:
Dynamic memory access only works inside function
(1 answer)
Closed last year.
I have a question on which I seek clarity with pointers. I am coming from javascript so I am having a hard time with pointers. I have written singly linked list code mostly by myself and the code is fully working. I have created a function to delete the particular item in the linked list. The function in the main is this:
insertAtMiddle(&head, 3, 500);
insertAtMiddle(&head, 100, 500);
There is one thing I can't understand. First I would like to show the code of my delete function.
void insertAtMiddle(node_t **head, int location, int newData){
node_t *temp = *head;
while(temp->next != NULL){
if (temp->data == location)
{
break;
}
//Shouldn't that also change the original head or move the head to the left as it is passed by reference
temp=temp->next;
}
if (temp->data != location)
{
printf("No location found for replacement!");
}
//Create new node
node_t *newNode = malloc(sizeof(node_t));
newNode->data = newData;
newNode->next = temp->next;
temp->next = newNode;
}
My question is shouldn't the temp=temp->next; inside the while loop should also affect or modify the original head? Head has been passed as a reference to this function. My confusion arises because *temp = *head, temp has been assigned head.
My full code:
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int data;
struct node *next;
} node_t;
void viewAllNodes(node_t *head){
node_t *tmp = head;
printf("\n");
while (tmp != NULL)
{
printf("%d--->", tmp->data);
tmp=tmp->next;
}
printf("\n");
}
void insertAtBegining(node_t **head, int data){
node_t *tmp = malloc(sizeof(node_t));
tmp->data = data;
tmp->next = *head;
*head = tmp;
}
void deleteNode(node_t **head,int data){
node_t *tmp = *head, *nodeToDelete = NULL;
//see two nodes in advance
while(tmp->next != NULL){
if (tmp->next->data == data)
{
nodeToDelete = tmp->next;
break;
}
tmp = tmp->next;
}
if (nodeToDelete == NULL)
{
printf("No node found to delete");
return;
}
tmp->next = nodeToDelete->next;
free(nodeToDelete);
}
void insertAtEnd(node_t **head, int data){
node_t *newNode = malloc(sizeof(node_t));
newNode->data = data;
newNode->next = NULL;
node_t *tmp = *head;
while (tmp->next != NULL)
{
tmp = tmp->next;
}
tmp->next = newNode;
}
node_t *searchNode(node_t *head, int value){
node_t *tmp = head;
while (tmp->next != NULL)
{
if(tmp->data == value){
return tmp;
}
tmp=tmp->next;
}
return NULL;
}
void insertAtMiddle(node_t **head, int location, int newData){
node_t *temp = *head;
while(temp->next != NULL){
if (temp->data == location)
{
break;
}
//Shouldn't that also change the original head as it is passed by
temp=temp->next;
}
if (temp->data != location)
{
printf("No location found for replacement!");
}
//Create new node
node_t *newNode = malloc(sizeof(node_t));
newNode->data = newData;
newNode->next = temp->next;
temp->next = newNode;
}
int main(){
node_t *head = NULL;
insertAtBegining(&head, 1);
insertAtBegining(&head, 2);
insertAtBegining(&head, 3);
insertAtBegining(&head, 4);
insertAtBegining(&head, 5);
insertAtBegining(&head, 6);
insertAtEnd(&head, 8);
insertAtEnd(&head, 9);
insertAtBegining(&head, 100);
viewAllNodes(head);
deleteNode(&head, 1);
deleteNode(&head, 8);
insertAtMiddle(&head, 3, 500);
insertAtMiddle(&head, 100, 500);
viewAllNodes(head);
return 0;
}
You are basically doing this:
#include <stdio.h>
void foo(int* head) {
int temp = *head;
temp = 1234;
}
int main()
{
int bar = 0;
foo(&bar);
printf("bar = %d\n", bar);
}
You expect 1234 as output, but the actual output is 0.
temp is just a local copy, modifying temp will just modify temp and nothing else.

c linked list delete smallest element [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
Lists seem really hard for me. I want to find the smallest element in a file: 1 5 8 6 4 8 6 48 9. It's 1 and I want to delete that 1. I can find the smallest element but can not delete it. I find the smallest element place but not the value. I tried copying deleting function from the web, however I cant understand it due to the fact that I'm really new to C. It writes an error that dereferencing to incomplete type. Please help. Post whole code because it should be more convenient to understand.
#include <stdio.h>
#include <stdlib.h>
typedef struct linkedList {
int value;
struct linkedList *next;
} linkedList, head;
linkedList *readList(linkedList *head) {
FILE *dataFile;
dataFile = fopen("duom.txt", "r");
if (dataFile == NULL) {
printf("Nepasisekė atidaryti failo\n");
} else {
printf("Duomenų failą pavyko atidaryti\n");
}
while (!feof (dataFile))
if (head == NULL) {
head = malloc(sizeof(linkedList));
fscanf(dataFile, "%d", &head->value);
head->next = NULL;
} else {
struct linkedList *current = head;
struct linkedList *temp = malloc(sizeof(linkedList));
while (current->next != NULL) {
current = current->next;
}
fscanf(dataFile, "%d", &temp->value);
current->next = temp;
temp->next = NULL;
}
return head;
}
void search(linkedList *head, int *lowest) {
int a[100];
int i = 0;
int minimum;
int b = 0;
linkedList *current = head;
while (current != NULL) {
a[i] = current->value;
current = current->next;
i++;
}
b = i;
i = 0;
minimum = a[0];
while (b > 0) {
if (minimum > a[i]) {
minimum = a[i];
lowest = i;
}
i++;
b--;
}
}
void deleteNode(struct node **head_ref, int key) {
struct node* temp = *head_ref, *prev;
if (temp != NULL && temp->data == key) {
*head_ref = temp->next; // Changed head
free(temp); // free old head
return;
}
while (temp != NULL && temp->data != key) {
prev = temp;
temp = temp->next;
}
if (temp == NULL)
return;
prev->next = temp->next;
free(temp);
}
void printList(linkedList *head) {
linkedList *current = head;
while (current != NULL) {
printf("%d->", current->value);
current = current->next;
}
printf("NULL\n");
return;
}
int main() {
linkedList *A = NULL;
A = readList(A);
search(A);
head = head->next;
minimum = head->value;
headk->next = head->next;
free(head);
printList(A);
return 0;
}
like this
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
typedef struct linkedList{
int value;
struct linkedList *next;
} linkedList, node;
linkedList *readList(void){
FILE *dataFile;
dataFile = fopen("duom.txt", "r");
if(dataFile == NULL) {
perror("file open");
return NULL;
}
int v;
node head = {0, NULL}, *curr = &head;
while (1 == fscanf(dataFile, "%d", &v)){
node *new_node = malloc(sizeof(node));
if(new_node == NULL){
perror("malloc");
break;
}
new_node->value = v;
new_node->next = NULL;
curr = curr->next = new_node;
}
fclose(dataFile);
return head.next;
}
int searchMin(linkedList *head){
if(head == NULL){
fprintf(stderr, "%s: The list MUST NOT be NULL.\n", __func__);
return INT_MIN;
}
int min = head->value;
node *p = head->next;
while(p){
if(p->value < min)
min = p->value;
p = p->next;
}
return min;
}
void deleteNode(node **head_ref, int key){
node *curr = *head_ref, *prev = NULL;
while (curr != NULL && curr->value != key){
prev = curr;
curr = curr->next;
}
if (curr == NULL) return;//not found
if(prev)
prev->next = curr->next;
else
*head_ref = curr->next;
free(curr);
}
void printList(linkedList *head){
node *current = head;
while (current != NULL) {
printf("%d->", current->value);
current = current -> next;
}
puts("NULL");
}
void freeList(linkedList *list){
while(list){
node *temp = list;
list = list->next;
free(temp);
}
}
int main(void){
linkedList *A = readList();
int min = searchMin(A);
printList(A);
deleteNode(&A, min);
printList(A);
freeList(A);
return 0;
}
Please try if this program can help you.
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
struct node {
int data;
struct node *next;
};
void push(struct node **head_ref, int new_data) {
struct node *new_node = (struct node *) malloc(sizeof(struct node));
new_node->data = new_data;
new_node->next = (*head_ref);
(*head_ref) = new_node;
}
void deleteNode(struct node **head_ref, int key) {
struct node *temp = *head_ref, *prev;
if (temp != NULL && temp->data == key) {
*head_ref = temp->next;
free(temp);
return;
}
while (temp != NULL && temp->data != key) {
prev = temp;
temp = temp->next;
}
if (temp == NULL) return;
prev->next = temp->next;
free(temp);
}
void printList(struct node *node) {
while (node != NULL) {
printf(" %d ", node->data);
node = node->next;
}
}
void min(struct node **q) {
struct node *r;
int min = INT_MAX;;
r = *q;
while (r != NULL) {
if (r->data < min) {
min = r->data;
}
r = r->next;
}
printf("The min is %d", min);
deleteNode(q, min);
printf("\n");
}
int main() {
struct node *head = NULL;
FILE *file = fopen("duom.txt", "r");
int i = 0;
fscanf(file, "%d", &i);
while (!feof(file)) {
push(&head, i);
fscanf(file, "%d", &i);
}
fclose(file);
puts("Created Linked List: ");
printList(head);
min(&head);
puts("\nLinked List after Deletion of minimum: ");
printList(head);
return 0;
}
file duom.txt
1 5 8 6 4 8 6 48 9
Test
./a.out
Created Linked List:
9 48 6 8 4 6 8 5 1 The min is 1
Linked List after Deletion of minimum:
9 48 6 8 4 6 8 5 ⏎

Sort a Linked list using C

I am trying to sort a Linked list, but not able to do it. Below is my code. Can anyone help me. I have seen some programs too, which sort linked list and their approach is also like this only.
#include <stdio.h>
#include <stdlib.h>
struct node {
int data;
struct node *next;
};
int push(struct node **h, int x)
{
struct node *temp = (struct node*)malloc(sizeof(struct node));
temp->data = x;
temp->next = *h;
*h = temp;
return 0;
}
void print(struct node *head)
{
struct node *temp = head;
while(temp != NULL)
{
printf("%d ",temp->data);
temp = temp->next;
}
printf("\n");
}
void sort(struct node **h)
{
int i,j,a;
struct node *temp1;
struct node *temp2;
for(temp1=*h;temp1!=NULL;temp1=temp1->next)
{
for(temp2=temp1->next;temp2!=NULL;temp2=temp2->next)
{
a = temp1->data;
temp1->data = temp2->data;
temp2->data = a;
}
}
}
int main()
{
struct node * head = NULL;
push(&head,5);
push(&head,4);
push(&head,6);
push(&head,2);
push(&head,9);
printf("List is : ");
print(head);
sort(&head);
printf("after sorting list is : ");
print(head);
return 0;
}
Below is the output which i am getting :
List is : 9 2 6 4 5
after sorting list is : 5 4 6 2 9
You're switching the elements no matter what. Compare them first and then swap them if temp2 is less than temp1:
void sort(struct node **h)
{
int i,j,a;
struct node *temp1;
struct node *temp2;
for(temp1=*h;temp1!=NULL;temp1=temp1->next)
{
for(temp2=temp1->next;temp2!=NULL;temp2=temp2->next)
{
if(temp2->data < temp1->data)
{
a = temp1->data;
temp1->data = temp2->data;
temp2->data = a;
}
}
}
}
In your bubble sort, you forget the swap condition.
In my opinion, I suggest insertion sort
#include <stdio.h>
#include <stdlib.h>
struct node {
int data;
struct node *next;
};
int push(struct node **h, int x)
{
struct node *temp = (struct node*)malloc(sizeof(struct node));
temp->data = x;
if (*h == NULL) {
temp->next = *h;
*h = temp;
} else {
struct node *tmp = *h;
struct node *prev = NULL;
while (1) {
if (tmp == NULL || tmp->data >= temp->data)
break;
prev = tmp;
tmp = tmp->next;
}
temp->next = tmp;
if (prev != NULL)
prev->next = temp;
else
*h = temp;
}
return 0;
}
void print(struct node *head)
{
struct node *temp = head;
while(temp != NULL)
{
printf("%d ",temp->data);
temp = temp->next;
}
printf("\n");
}
int main()
{
struct node * head = NULL;
push(&head,5);
push(&head,4);
push(&head,6);
push(&head,2);
push(&head,9);
printf("List is : ");
print(head);
//sort(&head);
printf("after sorting list is : ");
print(head);
return 0;
}

Resources