t1msu
t1msu

Reputation: 13

C: read string into dynamic array

Hi im trying to read user input of "unlimited" length into an char array. It works fine for shorter strings, but for more than around 30 characters the programm crashes. Why does this happen and how can i fix this?

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

char* read_string_from_terminal()//reads a string of variable length and returns a pointer to it
{
    int length = 0; //counts number of characters
    char c; //holds last read character
    char *input;

    input = (char *) malloc(sizeof(char)); //Allocate initial memory

    if(input == NULL) //Fail if allocating of memory not possible
    {
        printf("Could not allocate memory!");
        exit(EXIT_FAILURE);
    }

    while((c = getchar()) != '\n') //until end of line
    {
        realloc(input, (sizeof(char))); //allocate more memory
        input[length++] = c; //save entered character
    }

    input[length] = '\0'; //add terminator
    return input;

}

int main()
{
    printf("Hello world!\n");
    char* input;
    printf("Input string, finish with Enter\n");
    input = read_string_from_terminal();
    printf("Output \n %s", input);
    return EXIT_SUCCESS;
}

Upvotes: 0

Views: 3831

Answers (1)

chux
chux

Reputation: 153328

realloc(input, (sizeof(char))); //allocate more memory only allocates 1 char. Not 1 more char. @MikeCAT

(sizeof(char)*length+1) is semantically wrong. Should be (sizeof(char)*(length+1)), but since sizeof (char) == 1, it makes no functional difference.

Need space for the null character. @MikeCAT

Should test for reallocation failure.

char c is insufficient to distinguish all 257 different responses from getchar(). Use int. getchar() may return EOF. @Andrew Henle

Minor: Better to use size_t for array indexes than int. int maybe too narrow.

In the end code needs to do something like:

size_t length = 0;
char *input = malloc(1);
assert(input); 
int c;
...
while((c = getchar()) != '\n' && c != EOF) {
  char *t = realloc(input, length + 1);
  assert(t); 
  input = t;
  input[length++] = c;
}
...
return input;

int main(void) {
  ...
  input = read_string_from_terminal();
  printf("Output \n %s", input);
  free(input);
  return EXIT_SUCCESS;
}    

Upvotes: 1

Related Questions