Ошибка сегментации 11 при попытке прочитать текстовый файл и q отсортировать его - PullRequest
0 голосов
/ 09 апреля 2019

Получение ошибки сегментации 11 при попытке прочитать в файле .txt и выполнить q-сортировку в C. Это домашнее задание для моего класса CS, и в нем профессор дал нам функцию q-sort он написал, и нам нужно сделать это быстрее, используя posix. Здесь я показываю соответствующий код для чтения в текстовом файле, а затем создаю массив и использую в нем q-сортировку. Программа работает с произвольным массивом строк, которые я составил, поэтому я вполне уверен, что это как-то связано с тем, как я читаю в файле .txt и обрабатываю его. Poem.txt находится в том же каталоге, и обработчик ошибок работает, если я изменяю имя файла. Есть идеи?

int main(){
double start, end;
double total;
char *array[100000];
char buffer[MAX_LENGTH];
int i = 0;
FILE *fp;
fp = fopen("poem.txt", "r");
if (fp < 0) {
    fprintf(stderr, "Couldn't open file to read in. | error number %d : %s \n", errno, strerror(errno));
    exit(1);
}
// First "function" to read in a text file for sorting

while (fscanf (fp, "%s", buffer) == 1) {
    array[i] = malloc (MAX_LENGTH);
    strcpy (array[i++], buffer);
}
// printf ("%s\n", array[1]);  /* print for troubleshooting */ 
start = clock();
sortThreaded (array, i);
// freeing the memory used in the array from Malloc
for (int j = 0; array[j]; j++){
    free(array[j]);
}
end=clock();
total = (end-start)/CLOCKS_PER_SEC;
printf(" total clocks: %f\n", total);
fclose(fp);
return 0;
}

Ответы [ 2 ]

0 голосов
/ 09 апреля 2019

Сначала, как отмечалось выше, вы должны проверить

if (NULL == fp)

not

if (fp < 0)

Поскольку fopen возвращает NULL, если не может открыть файл.

Во-вторых, небезопасно использовать% s в fscanf.Если длина строки ввода превышает MAX_LENGTH, вы можете получить «* обнаружен разрыв стека *».

Вы можете использовать

char *fgets(char *s, int size, FILE *stream);

или

fscanf (fp, "%99999s", buffer)

Даже если это не должно быть проблемой.

В-третьих, массив не инициализирован.Итак, он содержит мусор.В

for (int j = 0; array[j]; j++) {
    free(array[j]);
}

Вы можете освобождать некоторые адреса, которые не были выделены.Как и в случае

fclose(fp);
0 голосов
/ 09 апреля 2019

Пара замечаний / возможностей, которые я вижу:

Если при проверке fp произойдет сбой fopen(), для него будет задано значение NULL, а не отрицательное число, так что это может быть источником или ошибкой.

if (fp == NULL) {
    fprintf(stderr, "Couldn't open file to read in. | error number %d : %s \n", errno, strerror(errno));
    exit(1);
}

Когда вы делаете fscanf и strcpy(), буфер может переполниться, лучше всего сделать fgets() и strncpy() и указать MAX_LENGTH

 while (fgets (buffer, MAX_LENGTH, fp) != NULL) {
        array[i] = malloc (MAX_LENGTH);
        strncpy (array[i++], buffer, MAX_LENGTH);
    }

Цикл free() может использовать тот же итератор i и декремент, чтобы быть уверенным, что мы освобождаем все, что мы выделили, не больше, не меньше.

while (--i >= 0){
    free(array[i]);
}

Ошибка сегментации обычно возникает, когда вы пытаетесь получить доступ к памяти, к которой у вас нет доступа или которой нет. Иногда выбрасывается MPU (блок защиты памяти).

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