Чтение строки из файла вызывает сбой - PullRequest
1 голос
/ 21 октября 2011

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

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] = '\0';
}

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

Ответы [ 3 ]

6 голосов
/ 21 октября 2011

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

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] = '\0';
}

Ваша проблема в том, что вы звонили 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.

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

6 голосов
/ 21 октября 2011

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

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

2 голосов
/ 21 октября 2011

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

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