Проблема с free () при чтении нескольких текстовых файлов (или выполняется дважды?) - PullRequest
0 голосов
/ 30 апреля 2018

У меня проблемы с определенной частью моего кода, когда дело доходит до чтения в нескольких файлах. Вот основная часть этого:

    char *a;
    int ch;
    char *line = NULL;
    char *prev_line[999];
    size_t len = 0;
    size_t read;
    if (argc > 1)
    {
      int i = 1;
      FILE *fp;
      while (i < argc)
      {
          a = malloc (MAX_NAME_SZ * sizeof (char));
          fp = fopen (argv[i], "r");
          if (fp == NULL)
          {
              /*Error statement in case an file doesn't exist */
          }
          else
          {
              while ((read = getline(&line, &len, fp)) != -1) {
                  if (strncmp(line, prev_line, read) != 0) {
                      strncat(a, line, read);
                      strncpy(prev_line, line, read);          
                  }
              }
              free(line); 

              fclose (fp);
              changeCase (a);
              printf ("\n");

          }
          i++;            
      }  
   }
   else
   {
       a = malloc (MAX_NAME_SZ * sizeof (char));
       fgets (a, MAX_NAME_SZ, stdin);
       changeCase (a);
       printf ("\n");
    }
}

но моя проблема состоит из этой части.

while ((read = getline(&line, &len, fp)) != -1) {
    if (strncmp(line, prev_line, read) != 0) {
        strncat(a, line, read);
        strncpy(prev_line, line, read);          
    }
}
free(line); 

Эта часть кода читает только те строки, которые являются уникальными для предыдущей строки. Однако, когда у меня есть несколько аргументов, и этот код проходит дважды, я получаю ошибку двойного освобождения или повреждения, которая, как я полагаю, происходит потому, что free (строка) выполняется дважды.

Есть ли где-то еще в коде, что я должен переместить это, или что-то, что я мог бы заменить его?

1 Ответ

0 голосов
/ 30 апреля 2018

Согласно документации getline() :

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

В вашем случае line будет нулевым только для первого файла. Вызов getline() устанавливает line для указания на то, что затем освобождается.

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

Установка line обратно на NULL после освобождения должна решить вашу проблему.

free(line);
line = NULL;

Это должно заставить getline() выделять новую память для каждого читаемого файла.

...