Search code examples
cstringmallocstdingetchar

Creating String through malloc and getchar()


So I'm trying to write a program that basically creates a string through memory allocation, reading character per character, but through only one input from the keyboard. I know there are multiple (better) ways to do it, but I wanted to do it through this particular way! Here's the code:

int newstring (char** string)
{
printf("--------------In function newstring--------------\n");
int i = 0;
string = malloc ( sizeof (char) );
printf("Adress: %p\n", (void*)string);
if (string == NULL)
  return -1;

while ( 1 )
{
printf("Pre-scan\n");
*(string[i]) = getchar();
printf("After-scan\nstring[%d] = %c\n", i, *(string[i]));
i++;
if ( *(string[i-1]) == '\n')
  break;
printf("Reallocation to size %d\n", i+1);
string = realloc ( string, sizeof (char) * (i+1) );
if (string == NULL)
  return -1;
}

string[i-1] = '\0';
printf("--------------Exit function newstring--------------\n");
return;
}

int main()
{
char *string;
newstring ( &string );
printf("%s\n", string);
}

The problem is that the program always crashes midway before reading the 3rd character, here are the printfs that occurred:

Adress: 00AE1578
Pre-scan
 1st Input:  >>Hello
After-scan
string[0] = H
Reallocation to size 2
Pre-scan
After-scan
string[1] = e
Reallocation to size 3
Pre-scan

I've wondered if it's because of the buffer having some sort of limit but I find it hard to believe the limit is 2 characters (I've tried multiple inputs, always gets stuck before 3rd character). Also tried with "scanf ("%c", *(string[i]) )" to the same result.


Solution

  • The problem starts with this:

    string = malloc ( sizeof (char) );
    

    Here string is a pointer to the actual pointer. You need to dereference it:

    *string = malloc ( sizeof (char) );
    

    Then the problem continues with

    *(string[i]) = getchar();
    

    You dereference the wrong thing, it should be

    (*string)[i] = getchar();
    

    Same with the other places where you use the wrong dereferencing.

    And then

    string[i-1] = '\0';
    

    Here you don't dereference the pointer at all. Should be

    (*string)[i-1] = '\0';
    

    Finally, the getchar function returns an int. This is important when you check if the function failed or not by comparing the result to EOF. You do not do this at all.