Конфликт назначения массива вил - PullRequest
0 голосов
/ 26 сентября 2019

У меня есть следующее и я пытаюсь читать из файла построчно, а затем помещать эту строку в массив.

char **history = malloc(sizeof(char*) * 1000);
int history_size = 0;

fp = fopen(file, "r");
if (fp == NULL)
    exit(EXIT_FAILURE);

while ((read = getline(&line, &len, fp)) != -1) {
    if(strstr(line, "\n") != NULL) {
        line[strlen(line) - 1] = '\0';
    }

    if (strcmp(line, "History") == 0) {
        for(int m = 0; m < history_size; m++) {
            printf("%s\n", history[m]);
        }
    } else {
        //printf("....%s\n", line);
        history[history_size++] = line;
    }
}

fclose(fp);
if (line)
    free(line);

Проблема в том, что массив не собирает строки, и когда я запускаю код, он печатает«История» столько же строк, сколько в файле.Я не мог справиться с этим в течение нескольких дней.История должна сохранять строки, которые происходят перед строкой истории.

1 Ответ

3 голосов
/ 26 сентября 2019

Это не имеет ничего общего с fork().

С справочной страницы из getline:

Если * lineptr равен NULL, то getline() выделит буфер для хранения строки, который должен быть освобожден пользовательской программой.(В этом случае значение в * n игнорируется.)

Если буфер недостаточно велик для размещения строки, getline () изменяет его размер с помощью realloc (3), обновляя * lineptr и * n какобязательно.

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

Итак, наконец, когда вы достигнете условия, когда ваш lineэто "History", они просто показали, что line содержало (то есть "История"), потому что все они указали на тот же адрес, что и line.

Это основная причина проблемы, но fork() наверняка отклонит вас от того, как вы хотите, чтобы ваш вывод впоследствии.* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 10 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *]]]]]].вы делаете execvp(), если fork() == 0, это не должно вызывать проблем.Все, что вам нужно сделать, это:

history[history_size] = malloc(sizeof(char)* (strlen(line)+1));
strcpy(history[history_size++], line);

вместо прямого назначения.

2) Не забывайте free() на каждой итерации память, выделяемую getline() в line.

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