qsort создает неопределенное c количество нулей - PullRequest
1 голос
/ 11 января 2020

Таким образом, моя программа читает целые числа из файла, пропуская строки, начинающиеся с #, затем сохраняет их в массиве и распечатывает их, отсортированные с использованием функции qsort. Однако, когда они печатаются, в начале по какой-то причине он печатает несколько нулей, а затем отсортированные числа. Если пары чисел 60, я получаю 21 ноль, если пары 103688, то печатает 60151 ноль.

Входной файл:

#Skip
#These
#Lines
25  8
25  19
25  23
25  28
25  29
25  30
25  33
25  35
25  50
25  54
25  55

Программа:

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


typedef struct {
    int start;
    int end;   
} path;

int cmp(const void *a,const void *b){
    int l=((path*)a)->start;
    int r=((path*)b)->start;

    if(l>r)
        return 1;
    if(l<r)
        return -1;
    if(l==r)
        return 0;
}

int doublesize(path** array,int n){
    path* new_array=malloc(n*2*sizeof(path));
    if(new_array==NULL){
        printf("Error allocating memory\n");
        abort();
    }

    for(int i=0;i<n;i++){
        new_array[i]=(*array)[i];
    }
    free(*array);
    *array=new_array;
    n*=2;
    return n;
}

int main()
{
    int maxsize=10;
    int test;
    path* array=malloc(maxsize*sizeof(path));
    if(array==NULL) {
        printf("Error allocating memory\n");
        abort();
    }

    FILE* fd=fopen("Test.txt","r");
    if(fd==NULL) {
        printf("Error opening file\n");
        abort();
    }
    char buff[200];
    int counter=0;

    char c;
    while(fgets(buff,200,fd)) {
        c=buff[0];
        if(c=='#') {
            continue;
        }
        sscanf(buff,"%d%d",&array[counter].start,&array[counter].end);
        counter++;
        if(counter==maxsize){
           maxsize=doublesize(&array,maxsize); 
        }
    }
    counter=0;
    qsort(&array[0],maxsize,sizeof(path),cmp);
    for(int i=0;i<maxsize;i++){
        printf("%d\t%d\n",array[i].start,array[i].end);
        if(array[i].start==0)
            counter++;
    }
    printf("%d\n",counter);
    fclose(fd);
    free(array);
    return 0;
}

1 Ответ

5 голосов
/ 11 января 2020

Вы сортируете и затем печатаете maxsize элементы, когда ваш массив содержит только counter элементов (после вашего первого while l oop). Вы должны использовать точное количество элементов при сортировке и при печати. ​​

Тот факт, что вы видите много 0, является просто совпадением. Когда вы выделяете пространство с помощью malloc(), содержимое вашего массива равно undefined , что означает, что все, что вы явно не перезаписываете, будет иметь неопределенное значение (это может быть 0 или это может быть другое случайное значение). Когда вы сортируете, все 0 будут перемещены в начало, но все остальное, что было неопределенным (а не 0), фактически попадет в середину ваших данных, возможно, станет неотличимым от реальных данных.

Это не ошибка qsort, это ошибка malloc (и, в конечном счете, ваша ошибка).

TL; DR: сохраняйте переменную, содержащую точное число элементов в массиве и никогда не работают после этого числа.

Быстрое решение (я пометил модификации с помощью ^^^):

int total = 0;
//  ^^^^^
int counter = 0;
char c;

while(fgets(buff, 200, fd)) {
    if(buff[0] == '#')
        continue;

    sscanf(buff,"%d%d", &array[counter].start, &array[counter].end);
    total++;
//  ^^^^^

    if(total == maxsize)
//     ^^^^^
        maxsize = doublesize(&array, maxsize);
}

qsort(&array[0], total, sizeof(path), cmp);
//               ^^^^^

for(int i = 0; i < total; i++){
//                 ^^^^^
    printf("%d\t%d\n", array[i].start, array[i].end);

    if(array[i].start == 0)
        counter++;
}
...