Search code examples
clinked-listeclipse-cdtstrcmp

strcmp in Linked List insertion crashing program


As part of an assignment, I'm supposed to implement a singly linked list in c. I've done this plenty of times before in a few different languages, but after a few hours of pain I've gotten stuck on a problem using strcmp. This is the structure I'm using:

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

The problem is specific to the insertion function, which is supposed to be similar to an insertion sort, since I need to have the nodes in the list sorted in alphabetical order.(my professor specified that the insertion function does the sorting, despite not calling it an insertion sort).

void insert(node **start, char *name, float score) { //  to insert a record into the linked list sorted by name in dictionary order.

//create new node
    node *n_node = new_node(name, score);

    node *current;
    current = *start;

    if (current != NULL) { //-----------if list is not empty
        node *prev = NULL;

        if (current->next != NULL) { //--if list has more than 1 element
            while (current != NULL && strcmp(name, current->name) > 0) { //cycle through list to sorted insertion point
             //                      ^^^^^^^Problem Here^^^^^^^^
            //while name is greater than current name, means lower on alphabet (z>a)
                prev = current;
                current = current->next;
            }
            if (current != NULL) { //-----not at end of list
            //once current is not < new node, connect between prev and current
                prev->next = n_node;
                n_node->next = current;
            } else { // ------------------at end of list
                prev->next = n_node;
            }

        } else { //-----------------------list has only one element
            current->next = n_node;
        }
    } else { //--------------------------List is empty - assign new node as first element
        *start = n_node;
    }

}

The problem is that my program crashes and burns without any errors or warnings (I'm using eclipse with CDT). The program works fine when while (current != NULL && strcmp(name, current->name) > 0) is modified to while (current != NULL /*&& strcmp(name, current->name) > 0*/).

It seems obvious to me that name or current->name are causing a problem with the operation of strcmp, but I can't seem to get around that.

Edit: I'll add that this function is called from another function, which retrieves and tokenises strings from a file containing pairs of names and marks, but my testing hasn't suggested that it passes a bad string or characters via the call.

For some extra detail, here's my new_node function:

node *new_node(char *name, float score) {
    node *new = (struct node*) malloc(sizeof(struct node));
    new->name = malloc(strlen(name) + 1);
    strcpy(new->name, name);
    new->score = score;
    new->next = NULL;
    return new;
}

(I realise using new as the name of the node isn't smart, and I will change that) and the function that calls insert:

int data_import(node **startp, char *infilename) { // to import data from the file and insert .
    int max_line = 100;
    char line[max_line];
    char delimiters[] = ",";

    char name[500] = "";
    char *namep;
    namep = &name[0];

    float score = 0.0f;
    int i = 0;

    FILE *fi;
    char *token;
    // open file to read
    fi = fopen(infilename, "r");
    if (fi == NULL) {  // Cannot open the file.
        perror("error");
        return 0;
    }

    // read each line, increase counter, retrieve data
    while (fgets(line, max_line, fi) != NULL) {
        //fputs(line, stdout);  //console output confirmation

        token = strtok(line, delimiters);
        strcpy(namep, token);
        token = strtok(NULL, delimiters); //increment token to mark variable
        score = atof(token);
        insert(startp, namep, score);

        i++;
    }
    //close file
    fclose(fi);
    return i;
}

Solution

  • what happens if you have element called apple as your first element and you try to add element called about ?

    you will be thrown out of below while loop straight away and your prev will be unassigned :

    while (current != NULL && strcmp(name, current->name) > 0) { //cycle through list to sorted insertion point
                 //                      ^^^^^^^Problem Here^^^^^^^^
                //while name is greater than current name, means lower on alphabet (z>a)
                    prev = current;
                    current = current->next;
                }
    

    this particular part looks suspicious to me :

    after that you will enter in below routine :

     if (current != NULL) { //-----not at end of list
                //once current is not < new node, connect between prev and current
                    prev->next = n_node;
                    n_node->next = current;
                }
    

    as your *prev is unassigned and you try to access it (prev->next = n_node;).you will get crash here.