M Mar
M Mar

Reputation: 29

segmentation fault in singly linked list

I am currently writing a program that implements a linked list to maintain a list on integers in sorted order. The program reads the integers from a file in the format of

d [\t] 7
i [\t] 8
i [\t] 7
i [\t] 10

with 'd' meaning delete from the list and 'i' inserting into the list, with no repeat integers allowed. This is the code I have so far:

#include <stdio.h>
#include <stdlib.h>

struct Node{
        int data;
        struct Node* next;
};

int delete(struct Node** head, int key){
        if(head == NULL)
        {
                return -1;
        }
        struct Node* ptr = *head;
        struct Node* prev = NULL;

        while(ptr->data != key && ptr->next!=NULL)
        {
                prev = ptr;
                ptr = ptr->next;
        }
        if(ptr->data == key)
        {
                if(prev)
                {
                        prev->next = ptr->next;
                }
                else
                {
                        *head = ptr->next;
                }
                free(ptr);
                return key;
        }
return -1;
}

int insert(struct Node** head, struct Node* newNode){
        struct Node* ptr;
        if(*head == NULL || (*head)->data >= newNode->data)
        {
        newNode->next = *head;
                *head = newNode;
        }
        else
        {
                ptr = *head;
                while(ptr->next != NULL && ptr->next->data < newNode->data)
                {
                        ptr = ptr->next;
                }
                newNode->next = ptr->next;
                ptr->next = newNode;
        }
        return 0;
}

int main(int argc, char* argv[]){
        FILE *fp = fopen(argv[1], "r");
        int num, found;
        char c;
        struct Node* head = NULL;
 struct Node* ptr = head;
        while(fscanf(fp, "%c\t%d\n", &c, &num)!=EOF)
        {
                for(ptr=head; ptr!=NULL; ptr=ptr->next)
                {
                        if(ptr->data == num)
                        {
                                found = 1;
                        }
                }
                if(found != 1)
                {
                        if(c == 'i')
                        {
                                struct Node *newNode = (struct Node*)malloc(sizeof(struct Node));
                                newNode->data = num;
                                newNode->next = NULL;
                                insert(&head, newNode);
                        }
                }
                if(c == 'd')
  delete(&head, num);
                }
                found = 0;
        }

        for(ptr=head; ptr!=NULL; ptr=ptr->next)
        {
                printf("%d ", ptr->data);
        }
return 0;
}

It works fine when the first letter is 'i', but whenever the first letter is 'd' I get a segmentation fault. Why is this?

Upvotes: 0

Views: 78

Answers (2)

Quentin Laill&#233;
Quentin Laill&#233;

Reputation: 125

whenever the first letter is 'd' I get a segmentation fault.

If the first letter is D, your list is still empty when you call delete.

In your first if, you need to dereference your pointer, as @SomeProgrammerDude mentionned.

Upvotes: 0

Some programmer dude
Some programmer dude

Reputation: 409176

When you try to delete a node first thing you do, the list is empty and inside the delete function *head (notice the dereference!) is a null pointer.

Since *head is a null pointer, so will ptr be, and you then dereference ptr without checking for that.

You might want to modify the initial check to be head == NULL || *head == NULL.

Upvotes: 2

Related Questions