Разрешить нарушение доступа - PullRequest
0 голосов
/ 20 сентября 2019

Сортировка массива строк в алфавитном порядке.

Я использовал сортировку выбора с библиотечной функцией strcmp()

#include "stdio.h"
#include "string.h"

main()
{
    int min;
    char *temp;
    char *str[] = {"Java", "Ruby", "Pyhton", "JavaScript", "JavaScrikt"};

    for (int i = 0; i < 5; i++)
    {
        min = i;
        for (int j = i + 1; j < 5; j++)
        {
            if (strcmp(str[min], str[j]) > 0)
            {
                min = j;
            }
        }
        if (strcmp(str[i], str[min]) != 0)
        {
            strcpy(temp, str[i]);
            strcpy(str[i], str[min]);
            strcpy(str[min], temp);
        }
    }
}

Я получил нарушение прав доступа.Почему это так и как я могу это исправить?

Ответы [ 2 ]

0 голосов
/ 20 сентября 2019

Я рекомендую вам включить все предупреждения компилятора.Когда я компилирую ваш код в Linux с -Wall (все предупреждения включены), я получаю:

robert@saaz:~$ gcc -Wall himi.c
himi.c: In function ‘main’:
himi.c:22:13: warning: ‘temp’ may be used uninitialized in this function [-Wmaybe-uninitialized]
             strcpy(temp, str[i]);
             ^~~~~~~~~~~~~~~~~~~~

Неинициализированный указатель всегда хорош для нарушения доступа (или ошибки сегментации в Unix), так каквы пытаетесь получить доступ к какой-то случайной памяти, которая не принадлежит вам, и операционная система дает вам пощечину (т. е. прерывает вашу неправильно работающую программу).

При этом, когда вы сортируете строки, обычно1007 * строки в памяти, вы просто переключаетесь вокруг указателей.Это намного быстрее, так как вам нужно только изменить указатели.Это также позволяет избежать сбоев с различной длиной строки: ваш код будет пытаться скопировать «JavaScript» (10 символов) в «Java» (4 символа).Запись в области памяти, которые вы не должны писать, может привести к сбою вашей программы (если вам повезет), или вы просто перезаписываете другие переменные и замечаете это только намного позже (получайте удовольствие отлаживая это).

Вот ваш обновленный код,Я также добавил код для печати отсортированного массива.

#include "stdio.h"
#include "string.h"

int main()
{
    int min;
    char *temp;
    char *str[] = {"Java", "Ruby", "Pyhton", "JavaScript", "JavaScrikt"};

    for (int i = 0; i < 5; i++)
    {
        min = i;
        for (int j = i + 1; j < 5; j++)
        {
            if (strcmp(str[min], str[j]) > 0)
            {
                min = j;
            }
        }
        if (strcmp(str[i], str[min]) != 0)
        {
            temp = str[i];
            str[i] = str[min];
            str[min] = temp;
        }
    }

    for (int i = 0; i < 5; i++)
    {
        printf("%s\n", str[i]);
    }
}
0 голосов
/ 20 сентября 2019

Вы забыли инициализировать темп.Вместо char *temp; поставить char temp[16].

...