0

When i run code it show realloc() invalid pointer error.

Is anything wrong in input() function?

#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 Answers 3

4

You make a few errors:

  • you return the end of the string, not the beginning.

  • realloc needs the original address (see Thomas' answer)

  • realloc may return a new address

  • you do not terminate the string.

The following fixes these errors and includes some suggestions:

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;
}
Sign up to request clarification or add additional context in comments.

11 Comments

I would suggest two changes: (1) Skip sizeof(char), which is always 1, and at least to me it is a code smell. (2) Use an integer as index into the allocated string instead of an extra pointer, to avoid the pointer arithmetic.
The code shown will fail miserably if EOF is detected before a new-line had been read.
This if (newstr != str) might invoke undefined behaviour, asstr might point to invalid memory after realloc().
@alk, fixed EOF. I am not sure about the undefined behavior comment. The str pointer (a variable) is compared with another pointer (variable), no matter if the memory pointed to is still valid. If it is undefined behavior, then it is not possible to check if the new pointer is different from the old pointer and the assignment must always be made.
"it is not possible to check if the new pointer is different from the old pointer" that's true. But one never needs to do this.
|
2

After doing str++, the pointer no longer points to the start of the allocated string. realloc needs the original pointer, not one that points to somewhere inside the allocated data.

Comments

0

An approach with no redundant calls and complete error checking:

#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;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.