user3699735
user3699735

Reputation: 21

Segfault when trying to sort a linked list of names by bubble sorting

I am trying to sort a linked list in alphabetical order using bubble sort, but I am getting a segfault when I run the program. I can print off the names before sorting, but when I sort them and try to display them, it doesn't work.

Here is the code that I have and the output I want is to just display the names in order.

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

#define MAX_STR_LEN 25
typedef struct Data_ {
    char *name;
    struct Data_ *next;
} Data;

Data* bubble_sort(Data *list);
Data* read_from_file(const char *file, const int size);
void display(Data *list);
void push(Data **head, char *name);

int main(int argc, char **argv) {
    if(argc != 2){
        printf("Not enough parameters!");
        exit(0);
    }

    Data *head = NULL;

    int size = 10;
    head = read_from_file(argv[1], size);
    printf("\nBefore sort");
    display(head);
    printf("\nBubble Sort\n");
    head = bubble_sort(head);
    display(head);
}

Data* bubble_sort(Data *head) {
    int count = 0, i;
    Data *start = head;
    Data *curr = NULL;
    Data *trail = NULL;
    Data *temp = NULL;

    //grab the count
    while(start != NULL) {
        count++;
        start = start->next;
    }

    for( i = 0; i < count; ++i) {
        curr = trail = head; //set curr and trail at the start node
        while(curr->next != NULL){
            if(strcmp(curr->name, curr->next->name) > 0) {
                temp = curr->next;
                curr->next = curr->next->next;
                temp->next = curr;
                if(curr==head)
                    head = trail = temp;
                else
                    trail->next = temp;
                curr = temp;
            }
            trail = curr;
            curr = curr->next;
        }
    }
    return head;
}

void push(Data **head, char *name) {
    Data *temp = malloc(sizeof(Data));
    temp->name = strdup(name);
    temp->next = *head;
    *head = temp;
}

Data* read_from_file(const char *file, const int size) {
    FILE *input;
    input = fopen(file, "r");
    Data *new_ = (Data*)malloc(sizeof(Data*));
    new_->next = NULL;
    int i;
    char name[MAX_STR_LEN];
    for(i = 0; i < size; i++) {
        fscanf(input, "%24s", &name);
        push(&new_, name);
    }
    return new_;
}

void display(Data *list) {
    Data *current = list;
    while(current->next != NULL) {
        printf("\n%s", current->name);
        current = current->next;
    }
}

The list of names that I read in is

Derek
Drew
Randell
Terrell
Carmen
Colin
Eddy
Pablo
Lamont
Dexter

Upvotes: 0

Views: 88

Answers (1)

user3121023
user3121023

Reputation: 8286

In addition to the problem pointed out by BLUEPIXY there were a couple of other problems in the code. I tested this and it seems to work.

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

#define MAX_STR_LEN 25
typedef struct Data_ {
    char *name;
    struct Data_ *next;
} Data;

Data* bubble_sort(Data *list);
Data* read_from_file(const char *file);
void display(Data *list);
void push(Data **head, char *name);

int main(int argc, char **argv) {
    if(argc != 2){
        printf("Not enough parameters!");
        exit(0);
    }

    Data *head = NULL;

    head = read_from_file(argv[1]);
    printf("\nBefore sort");
    display(head);
    printf("\nBubble Sort\n");
    head = bubble_sort(head);
    display(head);
}

Data* bubble_sort(Data *head) {
    int i = 1;
    Data *curr = NULL;
    Data *trail = NULL;
    Data *temp = NULL;
    Data *after = NULL;

    while( i == 1) { // keep sorting
        i = 0; // if not changed loop will exit
        curr = trail = head; //set curr and trail at the start node
        while(curr->next != NULL){
            if(strcmp(curr->name, curr->next->name) > 0) {
                i = 1; // still sorting
                after = curr->next;
                temp = after->next; // temp may be NULL. thats ok
                after->next = curr;
                curr->next = temp;
                if(curr==head) {
                    head = after;
                }
                else {
                    trail->next = after;
                }
                curr = after;
            }
            trail = curr;
            curr = curr->next;
        }
    }
    return head;
}

void push( Data **head, char *name) {
    Data *temp = malloc(sizeof(Data));
    temp->name = strdup(name);
    temp->next = *head;
    *head = temp;
}

Data* read_from_file(const char *file) {
    FILE *input;
    Data *new_ = NULL; // allocation will take place in push
    input = fopen(file, "r");
    char name[MAX_STR_LEN];
    while( fscanf(input, "%24s", name) == 1) { // scan until scan fails to return one value
        push( &new_, name);
    }
    return new_;
}

void display(Data *list) {
    Data *current = list;
    while(current != NULL) {
        printf("\n%s", current->name);
        current = current->next;
    }
}

Upvotes: 1

Related Questions