简体   繁体   English

快速排序抛出分段错误

[英]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.我必须写一个快速排序,得到一个具有最通用密码及其频率的txt

I also have a file main.c that must be correct.我还有一个必须正确的文件main.c。 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.我也使用了valgrind ,但我找不到错误。

Take a look, at the end of code is the result of valgrind .看一看,代码末尾是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:这是 VALGRIND 所说的:

==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:这告诉你在第 34 行有一个未初始化的值在使用。让我们看看第 34 行:

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

So either mylist or mylist->first is uninitialised.所以无论是mylist还是mylist->first都是未初始化的。 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)让我们深入研究您粘贴的跟踪,到下一行所示的第 90 行: ==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! mylist->first未初始化,因为它尚未分配给! 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 ;另请参阅BLUEPIXY留下的评论; they're useful points to consider.它们是值得考虑的有用点。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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