Hafiz Temuri
Hafiz Temuri

Reputation: 4112

Debug the Segment Fault in C

I am trying to make a sorted linked list. Everything looks fine, but I am getting a Segment Fault for some reason, not sure why. Any help would be appreciated. The problem lies in my while loop, I have commented that in the code below.

typedef struct node{
    char *name;
    struct node *next;
} node;

node* insert_node(node *head, char *name){
    node *temp, *pre, *next;
    temp = (node*) malloc(sizeof(node));
    temp->name = name;
    temp->next = NULL;

    if (!head){
        head = temp;
    } else {
        pre = NULL;
        next = head;
        //something is wrong with this while loop, not sure what though
        while(next && (strcmp(next->name, name) < 0) ){
            pre = next;
            next = next->next;
        }
        printf("out\n");
        if (!next){
            pre->next = temp;
        } else {
            if(pre){
                temp->next = pre->next;
                pre->next = temp;
            } else {
                temp->next = head;
                head = temp;
            }
        }
    }
    return head;
}

@qwn, asked me to have the different names of next node pointer and the temp node. @Jonathan Leffler, asked me to provide the complete code. So, here it is,

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

typedef struct node{
    char *name;
    struct node *next;
} node;

node* insert_node(node *head, char *name);
void print_links(node *head);
void free_links(node *head);
void parser(char *string);

int main (int argc, char *argv[]){
    char *string = "file1a.txt/file1b.txt/too_deep/dir1/file2a.txt/";
    parser(string);
}

void parser(char *s){
    node *head;
    char *tokens;
    char *string = strdup(s);
    tokens = strtok(string, "/");
    while (tokens != NULL){
        //printf("%s\n", tokens);
        head = insert_node(head, tokens);
        tokens = strtok(NULL, "/");
    }
    print_links(head);
    free_links(head);
    return;
}

node* insert_node(node *head, char *name){
    node *temp, *pre, *ptr;
    temp = (node*) malloc(sizeof(node));
    temp->name = name;
    temp->next = NULL;

    if (!head){
        head = temp;
    } else {
        pre = NULL;
        ptr = head;
        // problem lies in this while loop
        while(ptr && (strcmp(ptr->name, name) < 0) ){
            printf("here\n");
            pre = ptr;
            ptr = ptr->next;
        }
        printf("out\n");
        if (!ptr){
            pre->next = temp;
        } else {
            if(pre){
                temp->next = pre->next;
                pre->next = temp;
            } else {
                temp->next = head;
                head = temp;
            }
        }
    }
    return head;
}

Upvotes: 1

Views: 108

Answers (1)

CiaPan
CiaPan

Reputation: 9571

Your head variable is not initialized in parser(), and its undefined value is passed to insert_node(), so the first access to the value with if(!head) triggers Undefined Behavior.

The result is most probably 'false' (as in your case), so the control is passed to the else branch, where the head value is copied to the ptr variable. Consequently ptr is not NULL in the while loop's condition, so ptr->name is accessed prior to strcmp call – and you're lucky this time UB results in the memory access error at the location 'pointed to' by ptr, which results in a crash.

Solution:
Expand the declaration by initializer:

    node* head = NULL;

Upvotes: 3

Related Questions