segfault при чтении последней строки файла с помощью fgets () - PullRequest
0 голосов
/ 30 марта 2019

Я решаю проблему кодирования для назначения структур данных, и одна часть моего решения продолжает давать мне segfault: 11 при чтении последней строки текстового файла с использованием fgets ().

Я уже некоторое время искал в StackOverflow и не могу найти ту же ошибку, что и я. Я пробовал много способов решить проблему, но не могу понять, что именно не так.

int main() {
    **S = func();
    free(S);
    return 0;
}

char** func() {
    FILE *fStrings = fopen("file.txt", "r");
    if (fStrings == NULL) printf("Error opening 'file.txt'\n")
    int length = fileLength("file.txt");  // This returns just the number of lines in a file, works as intended.
    char **strings = (char **)malloc(200 * length * sizeof(char));
    f(length, (char (*)[200])strings, *fStrings);
    // some code using the data modified by f()
    fclose(fStrings);
    return strings;
}

void f(int length, char strings[][200], FILE *fStrings) {
    int i;
    for (i = 0; i <= length; i++) {
        printf("i = %d\n", i);  // debug
        fgets(strings[i], 200, fStrings);  // Here's the problem
        printf("string = %s\n", strings[i]);  // debug
    }
}

Приведенный выше код имеет 2 строки отладки, чтобы увидеть, где именно происходит ошибка. Функция вызывается с правильными параметрами, где length - это количество строк в массиве, strings - это массив строк, а fStrings - файл с указанными строками.

segfault возникает при попытке прочитать последнюю строку текстового файла. Любая помощь будет оценена.

РЕДАКТИРОВАТЬ: Изменен блок кода, чтобы включить лучшую версию моего кода, в случае, если это облегчает понимание. Также включены правильные библиотеки.

1 Ответ

0 голосов
/ 30 марта 2019

Я думаю, что главная проблема с вашим кодом - эта строка

for (i = 0; i <= length; i++) {

Из-за <= он будет циклически повторяться "длина + 1", но вы выделяете память только для "длины". Измените его на:

for (i = 0; i < length; i++) {

Ваше распределение странно. Вы должны выделить 2D-массив, используя указатель на 1D-массив, например, так:

char (*strings)[200] = malloc(length * sizeof *strings)

тогда вы можете сделать вызов без приведения.

Также только что заметил эту строку:

f(length, (char (*)[200])strings, *fStrings);
                                  ^
                                  notice

Не думаю, что вы хотите * перед fStrings (он даже не должен компилироваться с *)

При правильном распределении (как описано выше) вызов должен быть:

f(length, strings, fStrings);
...