简体   繁体   中英

Quick sort throwing segmentation fault

I have to write a quick sort, that gets a txt that have the most general password and its frequencies.

I also have a file main.c that must be correct. I only need to write the functions for the quick sort.

When I look at the code it seems all fine. I also used valgrind , but I can't find the errors.

Take a look, at the end of code is the result of valgrind .

#define _POSIX_C_SOURCE 200809L
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "quicksort.h"

void init_list(list *mylist) {
    mylist = (list*)malloc(sizeof(list));
    mylist->first = NULL;
    mylist->last = NULL;
}

void insert_list(list_element *le, list *mylist) {
    le->next = NULL;

    if (mylist->first == NULL) {
        mylist->first = le;
        mylist->first->next = NULL;

        if (mylist->last == NULL) {
            mylist->last = le;
        }
    } else
    if (mylist->first != NULL) {
        if (mylist->first->next == NULL) {
            mylist->first->next = le;
            mylist->last = le;
    } else
    if (mylist->first->next != NULL) {
            list_element *h = mylist->first->next;
            list_element *hc = NULL;
            while (h != NULL) {
                hc = h;
                h = h->next;
            }
            hc->next = le;
            mylist->last = le;
        }
    }
}

void free_list(list *mylist) {
    list_element *zaehler;
    list_element *zaehler2 = NULL;

    for (zaehler = mylist->first; zaehler != mylist->last; zaehler = zaehler2) {
        zaehler2 = zaehler->next;
        free(zaehler);
    }
    free(mylist);
}

void read_data(char *filename, list *mylist) {
    FILE *input = fopen(filename, "r");
    if (input == NULL) {
        printf("Could not open file\n");
        return;
    }
    char *zeile = malloc(50 * sizeof(char));
    char *leer = " ";
    while (fgets(zeile, 50, input) != NULL) {
        char *token1 = strtok(zeile, leer);
        char *token2 = strtok(NULL, "\n");
        list_element *new;
        new = (list_element*)malloc(sizeof(list_element));
        new->password = token1;
        new->count = atoi(token2);
        insert_list(new, mylist);
    }
}

list_element *partition(list *input, list *left, list *right) {
    list_element *pivot = input->first;
    list_element *zaehler = pivot->next;

    while (zaehler != input->last) {
        if (zaehler->count < pivot->count) {
            insert_list(zaehler, left);
        } else {
            insert_list(zaehler, right);
        }
    }
    if (zaehler == input->last) {
        if (zaehler->count < pivot->count) {
            insert_list(zaehler, left);
        } else {
            insert_list(zaehler, right);
        }
   }
    return pivot;
}

void qsort_list(list *mylist) {
    if (mylist->first == mylist->last) {
        return;
    } else {
        list *left = NULL;
        list *right = NULL;
        list_element *pivot;
        pivot = partition(mylist, left, right);
        qsort_list(left);
        qsort_list(right);
        if (left->first == NULL) {
            mylist->first = pivot;
        } else {
            mylist->first = left->first;
            left->last->next = pivot;
        }
        if (right->first == NULL) {
            pivot->next = NULL;
            mylist->last = pivot;
        } else {
            pivot->next = right->first;
            mylist->last = right->last;
        }
    }
}

void print_list(list *mylist) {
    list_element *first = mylist->first;
    list_element *last = mylist->last;
    list_element *zaehler;
    for (zaehler = first; zaehler != last; zaehler = zaehler->next) {
        printf("%s %d\n", zaehler->password, zaehler->count);
    }
    printf("%s %d\n", last->password, last->count);
}

this is what VALGRIND said:

==4996== Memcheck, a memory error detector
==4996== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==4996== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==4996== Command: ./a1 Eingabedaten_quicksort_unsortiert
==4996== 
==4996== Conditional jump or move depends on uninitialised value(s)
==4996==    at 0x4007DC: insert_list (introprog_quicksort.c:34)
==4996==    by 0x4009D1: read_data (introprog_quicksort.c:90)
==4996==    by 0x400C8C: main (main_quicksort.c:13)
==4996== 
==4996== Conditional jump or move depends on uninitialised value(s)
==4996==    at 0x400824: insert_list (introprog_quicksort.c:42)
==4996==    by 0x4009D1: read_data (introprog_quicksort.c:90)
==4996==    by 0x400C8C: main (main_quicksort.c:13)
==4996== 
==4996== Use of uninitialised value of size 8
==4996==    at 0x400831: insert_list (introprog_quicksort.c:43)
==4996==    by 0x4009D1: read_data (introprog_quicksort.c:90)
==4996==    by 0x400C8C: main (main_quicksort.c:13)
==4996== 
==4996== Use of uninitialised value of size 8
==4996==    at 0x40085E: insert_list (introprog_quicksort.c:47)
==4996==    by 0x4009D1: read_data (introprog_quicksort.c:90)
==4996==    by 0x400C8C: main (main_quicksort.c:13)
==4996== 
==4996== Use of uninitialised value of size 8
==4996==    at 0x40086E: insert_list (introprog_quicksort.c:48)
==4996==    by 0x4009D1: read_data (introprog_quicksort.c:90)
==4996==    by 0x400C8C: main (main_quicksort.c:13)
==4996== 
==4996== Invalid read of size 8
==4996==    at 0x40088C: insert_list (introprog_quicksort.c:52)
==4996==    by 0x4009D1: read_data (introprog_quicksort.c:90)
==4996==    by 0x400C8C: main (main_quicksort.c:13)
==4996==  Address 0x111e2d8d48550030 is not stack'd, malloc'd or (recently) free'd
==4996== 
==4996== 
==4996== Process terminating with default action of signal 11 (SIGSEGV)
==4996==  General Protection Fault
==4996==    at 0x40088C: insert_list (introprog_quicksort.c:52)
==4996==    by 0x4009D1: read_data (introprog_quicksort.c:90)
==4996==    by 0x400C8C: main (main_quicksort.c:13)
==4996== 
==4996== HEAP SUMMARY:
==4996==     in use at exit: 642 bytes in 4 blocks
==4996==   total heap usage: 5 allocs, 1 frees, 4,738 bytes allocated
==4996== 
==4996== 16 bytes in 1 blocks are definitely lost in loss record 1 of 4
==4996==    at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4996==    by 0x40079B: init_list (introprog_quicksort.c:24)
==4996==    by 0x400C72: main (main_quicksort.c:12)
==4996== 
==4996== LEAK SUMMARY:
==4996==    definitely lost: 16 bytes in 1 blocks
==4996==    indirectly lost: 0 bytes in 0 blocks
==4996==      possibly lost: 0 bytes in 0 blocks
==4996==    still reachable: 626 bytes in 3 blocks
==4996==         suppressed: 0 bytes in 0 blocks
==4996== Reachable blocks (those to which a pointer was found) are not shown.
==4996== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==4996== 
==4996== For counts of detected and suppressed errors, rerun with: -v
==4996== Use --track-origins=yes to see where uninitialised values come from
==4996== ERROR SUMMARY: 7 errors from 7 contexts (suppressed: 0 from 0)
Segmentation fault

In the future, it might help to ask a question about the error messages that you don't understand. Try something like "What does ... mean?" or "How do I decipher ...?".

 ==4996== Conditional jump or move depends on uninitialised value(s) ==4996== at 0x4007DC: insert_list (introprog_quicksort.c:34)

This tells you there's an uninitialised value in use at line 34. Let's take a look at line 34:

if ( mylist->first == NULL ) { //c.34

So either mylist or mylist->first is uninitialised. Let's delve deeper into the trace you pasted, to line 90 as indicated by the next line: ==4996== by 0x4009D1: read_data (introprog_quicksort.c:90)

new = (list_element*)malloc(sizeof(list_element));
new->password = token1;
new->count = atoi(token2);
insert_list(new, mylist); //c.90

Ahh! I see! mylist->first is uninitialised because it's not yet been assigned to! Coincidence much? I think not. This makes perfect sense.

Now that you've been briefed in reading these error messages, you should be able to go through the rest and clear them up too... Your segfault is likely caused by these errors.

See also the comments left by BLUEPIXY ; they're useful points to consider.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM