2017-02-03 10 views
1

Ich muss eine schnelle Art schreiben, die eine txt erhält, die das allgemeinste Passwort und seine Frequenzen haben. Ich habe auch eine Datei main.c, die korrekt sein muss Ich muss nur die Funktionen für die schnelle Sortierung schreiben.Schnelle Sortierung werfen Segmentierung Fehler

Wenn ich mir den Code anschaue, scheint alles in Ordnung zu sein. Ich habe auch valgrind verwendet, aber ich kann die Fehler nicht finden.

Schauen Sie, am Ende des Codes ist das Ergebnis 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); 
} 

das ist, was valgrind sagte:

==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 
+0

1) 'mylist = (Liste *) malloc (sizeof (Liste));' Keine Effektvariable der Aufruferseite (main). – BLUEPIXY

+0

2) 'list * left = NULL;': Dies ist kein Konstrukt 'list'. So kann es nicht bei 'insert_list (zaehler, links);' – BLUEPIXY

+0

Ich habe keine Deklaration der 'list' Struktur in Ihrem Code-Snippit gesehen. Wo wird das erklärt? Gleiches für "list_element". –

Antwort

1

In Zukunft könnte es eine Frage zu den Fehlermeldungen fragen helfen, die Sie nicht verstehen. Versuchen Sie etwas wie "Was bedeutet ...?" oder "Wie entziffere ich ...?".

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

Dies sagt Ihnen dort im Einsatz an der Linie 34. Nehmen wir ein uninitialised Wert ist ein Blick auf Linie 34:

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

Also entweder mylist oder mylist->first uninitialised wird. Lassen Sie sich tiefer in die Spur eingefügten, 90 an der Leitung, wie durch die nächste Zeile angezeigt: ==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! Aha! mylist->first ist nicht initialisiert, weil es noch nicht zugewiesen wurde! Zufall viel? Ich denke nicht. Das macht Sinn.

Nun, da Sie diese Fehlermeldungen gelesen haben, sollten Sie in der Lage sein, den Rest durchzugehen und sie auch zu löschen ... Ihr Segmentfehler wird wahrscheinlich durch diese Fehler verursacht.

Siehe auch die Kommentare von BLUEPIXY verlassen; Sie sind nützliche Punkte zu beachten.