realloc () ошибка неверного указателя при увеличении размера строки в функции - PullRequest
0 голосов
/ 03 ноября 2018

Когда я запускаю код, он показывает realloc() недопустимая ошибка указателя.

Что-то не так в функции input()?

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<time.h>
char *input(void)
{
    int n = 1;
    char *str = malloc(sizeof(char));
    *str = '\0';
    while((*str=getchar())!='\n')
    {
        n++;
        str = realloc(str,sizeof(char)*n);
        str++;
    }
    return str;
}

int main(int argc, char const *argv[])
{
    char *str = input();
    printf("%s",str);
    free(str);
    return 0;
}

Ответы [ 3 ]

0 голосов
/ 03 ноября 2018

Вы делаете несколько ошибок:

  • вы возвращаете конец строки, а не начало.

  • realloc нужен оригинальный адрес (см. Ответ Томаса)

  • realloc может вернуть новый адрес

  • вы не завершаете строку.

Следующее исправляет эти ошибки и включает некоторые предложения:

char *input(void)
{
    size_t i=0;
    int c;
    char *str = malloc(1);
    if (!str) return 0;
    while((c=getchar())!=EOF && c!='\n')
    {
        str[i]= c;
        if ((newstr = realloc(str,i+1))==0)
            break;          // out of memory: return what we have
        str= newstr;
        i++;
    }
    str[i]= '\0';
    return str;
}
0 голосов
/ 03 ноября 2018

Подход без лишних вызовов и полной проверки ошибок:

#include <stdio.h>
#include <stdlib.h>

char *input(void)
{
  size_t n = 0;
  char * str = NULL;

  do
  {
    ++n;

    {
      void * pv = realloc(str, (n + 1) * sizeof *str);
      if (NULL == pv)
      {
        perror("realloc() failed");

        break;
      }

      str = pv;
    }

    {
      int result = getchar();

      if (EOF == result)
      {
        if (ferror(stdin))
        {
          fprintf(stderr, "getchar() failed\n");
        }

        --n;

        break;
      }

      str[n - 1] = result;
    }
  } while ('\n' != str[n - 1]);

  if (NULL != str)
  {
    str[n] = '\0';
  }

  return str;
}

int main(int argc, char const *argv[])
{
  int result = EXIT_SUCCESS; /* Be optimistic. */

  char * str = input();
  if (NULL == str)
  {
    result = EXIT_FAILURE;

    fprintf(stderr, "input() failed\n");
  }
  else
  {
    printf("input is: '%s'\n", str);
  }

  free(str);

  return result;
}
0 голосов
/ 03 ноября 2018

После выполнения str++ указатель больше не указывает на начало выделенной строки. realloc нужен исходный указатель, а не тот, который указывает где-то внутри выделенных данных.

...