Чтение строки из файла вызывает сбой

#c #string

#c #строка

Вопрос:

Я пытаюсь прочитать строку из файла посимвольно и поместить символы в строку; вот «мой код:

 char *str = "";
size_t len = 1; /* I also count the terminating character */

char temp;
while ((temp = getc(file)) != EOF)
{
    str = realloc(str,   len * sizeof(char));
    str[len-2] = temp;
    str[len-1] = '';
}
  

Программа завершает работу в realloc строке. Если я перемещу эту строку за пределы цикла или закомментирую ее, она не вылетит. Если я просто читаю символы, а затем отправляю их в стандартный вывод, все работает нормально (т. Е. файл открыт правильно). В чем проблема?

Ответ №1:

Вы не можете realloc использовать указатель, который не был сгенерирован с malloc самого начала.

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

Комментарии:

1. И я вижу, что вы исправили одну за другой проблему в исходном вопросе. Очень хорошо.

Ответ №2:

Измените свой код на:

 char *str = NULL; // realloc can be called with NULL
size_t len = 1; /* I also count the terminating character */

char temp;
while ((temp = getc(file)) != EOF)
{
    str = (char *)realloc(str,   len * sizeof(char));
    str[len-2] = temp;
    str[len-1] = '';
}
  

Ваша проблема заключается в том, что вы вызывали realloc с указателем на память, которая не была выделена ни malloc тем, ни другим, или realloc которая не разрешена.

Со страницы realloc руководства:

 realloc() changes the size of the memory block pointed to by ptr to size bytes.
          The contents will be unchanged to the minimum of  the  old  and  new
          sizes; newly allocated memory will be uninitialized.  If ptr is NULL,
          then the call is equivalent to malloc(size), for all values of size;
          if size is equal to zero, and ptr is not NULL, then the call is
          equivalent to free(ptr).  Unless ptr is NULL, it must have been
          returned by an earlier call  to malloc(), calloc() or realloc().  If
          the area pointed to was moved, a free(ptr) is done.
  

Кстати, вам действительно не следует увеличивать буфер на один символ за раз, но оставьте два счетчика, один для емкости буфера, а другой для количества используемых символов, и увеличивайте буфер только тогда, когда он заполнен. В противном случае ваш алгоритм будет иметь действительно низкую производительность.

Комментарии:

1. В последнем операторе вашего кода ( str[len] = ''; ) вы записываете за пределы выделенной памяти str . Мне кажется, что у @Paul правильные индексы.

2. @DavidAlber, Пол быстро отредактировал вопрос, который не отображается в истории. Показанные здесь индексы взяты из оригинала, поэтому я сделал свой комментарий «off by one» в своем ответе.

3. @DavidAlber Спасибо, я скопировал операционный код, который содержал эту случайную ошибку. Я это исправил.

Ответ №3:

Вы не можете realloc использовать строковый литерал. Кроме того, realloc редактирование каждого нового символа — не очень эффективный способ сделать это. Посмотрите getline , расширение gnu.