ошибка сегментации в программе сортировки C - PullRequest
0 голосов
/ 07 сентября 2018

Я пишу код для сортировки txt-файла по int и затем отображаю их, когда пользователь запрашивает число с определенным индексом, но каждый раз, когда я запускаю свой код, я получаю ошибку сегментации. Что я могу сделать, чтобы это исправить?

void insert_sorted(long *sorted, int count, long value)
{
    int i = 0;

    sorted[1024] = value;
    if (count == 0) return;
    for (i = count; i >= 0; i--) {
        if (value < sorted[i - 1])
            sorted[i] = sorted[i - 1];
        else break;
    }
    sorted[i] = value;
}
int main(int argc, char *argv[])
{
    FILE *infile = NULL;
    int count = 0;
    long sorted[1024];
    long value;
    int i = 0;
    if (argc < 2) {
        fprintf(stderr, "Usage : %s <file_name>/n", argv[0]);
        return 1;
    }
    infile = fopen(argv[1], "r");
    if (NULL == infile) {
        perror("fopen");
        return -1;
    }
    /* while file not ends */
    while (!feof(infile)) {
        fscanf(infile, "%ld\n", &value); /* fetch value */
        insert_sorted(sorted, count, value); /* sort */
        ++count; /* increase number of sorted values */
    }
    /* display values */
    printf("Enter Index : ");
    int index;
    scanf("%d", &index);
    if (index == -1)
        fclose(infile);
    printf("%d ", sorted[index]);

    /* cleanup */
    if (infile) {
        fclose(infile);
        infile = NULL;
    }
    return 0;
}

Ответы [ 4 ]

0 голосов
/ 08 сентября 2018

Размер массива sorted равен 1024:

    long sorted[1024];

, что означает действительный индекс массива sorted в диапазоне от 0 до 1023.

В функции insert_sorted() вы пытаетесь получить доступ к массиву sorted вне его диапазона:

    sorted[1024] = value;
           ^^^^

Доступ к элементу массива сверх его размера является неопределенным поведением, которое включает в себя программу, которая может вызвать ошибку сегментации.

На самом деле в функции insert_sorted() есть логическая ошибка. Это никогда не сохраняет первое значение в соответствующем месте в массиве sorted из-за этой проверки значения count:

    if (count == 0) return;

Впервые значение count будет равно 0, и функция вернется без сохранения value в соответствующем месте в массиве sorted. Кроме того, вы должны установить значение count и, если оно больше размера массива, функция должна выдать соответствующее сообщение об ошибке. Вы можете сделать:

#define ARR_SZ 1024

void insert_sorted(long *sorted, int count, long value) {
    int i = 0;

    if (count > ARR_SZ) {
        fprintf (stderr, "Array is exhausted");
        //may you want to change the return type of function from void to 
        //int and return a value in case of error.
        //Based on the return value, the caller of this function can take
        //appropriate action.
        return;
    }

    for (i = count; i > 0; i--) {
        if (value < sorted[i - 1])
            sorted[i] = sorted[i - 1];
        else 
            break;
    }
    sorted[i] = value;
}

int main(int argc, char *argv[])
{
    FILE *infile = NULL;
    int count = 0;
    long sorted[ARR_SZ];
    ......
    ......
    ......
}

Когда вы принимаете index ввод от пользователя, обязательно добавьте проверку, является ли он меньше 0 или больше или равен count. Если это так, вы не должны получить доступ к sorted[index].

    scanf("%d", &index);

    if ((index >= count) || (index < 0)) {
         //print error message and do not access sorted[index]
    }

Тебе это не нужно:

    if (index == -1)
        fclose(infile);

из-за этого, когда пользователь вводит -1, fclose вызывается дважды для infile. Убедитесь, что как только вы закрыли FILE * открытого файла, не вызывайте fclose снова для него.

0 голосов
/ 08 сентября 2018

Операция в отсортированном виде [1024] = значение; вылетит ваша программа. Размер отсортированного массива - всего 1024, поэтому самый большой индекс - 1023.

Один из способов исправить это - изменить размер сортировки на 1025 в функции main ().

Другая операция в цикле for, которая может привести к сбою программы: при i = 0 доступ к отсортированному [i - 1] отловит исключение.

0 голосов
/ 08 сентября 2018

Ошибка сегментации появляется при попытке записи в массив элементов с ключом, который больше его измерения. В этом случае вы пишете на

sorted[1024] = value

с наибольшим ключом 1023 (длинная сортировка [1024] означает от 0 до 1023).

Вы должны изменить

long sorted[1024];

с

long sorted[1025];

иначе вы должны изменить

sorted[1024] = value;

с

sorted[1023] = value;

Я не читал твой код, чтобы сказать, что лучше.

0 голосов
/ 08 сентября 2018

Что я могу сделать, чтобы это исправить?

Вы можете запустить программу в отладчике.

Вы можете либо шагать по коду, по одной инструкции за раз, проверяя значения ваших переменных по ходу, либо вы можете просто позволить программе работать под пристальным взглядом отладчика. Если и когда программа вызывает ошибку сегмента, отладчик прервет ее в точном месте сбоя, что позволит вам увидеть, какой код ответственен. Он даже позволит вам увидеть значения задействованных переменных, если есть какие-либо сомнения относительно того, почему код сделал то, что сделал.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...