Search code examples
carraysmemory-managementsegmentation-faultdynamic-memory-allocation

Why am I getting a segmentation fault when reading characters from console and storing in an array?


I'm trying to write a program that will read characters from stdin into a character array, so I can then perform other operations on that array. I wrote the program to dynamically allocate more memory for the array when needed. However, I always get a segmentation fault once I end the input of the program.

Notes:

  • I'm using an int, not a char, to store the characters being read in, so I believe the comparison to EOF should be valid?
  • The ch == 'l' line is just there because I got tired of pressing Ctrl+D twice, it'll be removed once I get this problem solved.

The following is inside main, with stdlib/stdio #included at the beginning of the program:

int arrCount = 0, arrSize = 200, ch, key_data_len;
char* input = malloc(arrSize * sizeof(char));

printf("Input is an array of %d characters that takes up %d bytes.\n", arrSize, arrSize * sizeof(char));

// Add characters to array until input is finished.
while ( (ch = (int) getchar()) != '\0' && ch != EOF) {
  if(arrCount >= arrSize)
  { 
    printf("GOT IN IF STATEMENT.");
    // If the array has not been initialized, fix that.
    if (arrSize == 0)
      arrSize = 200 * sizeof(char);

    // Make the reallocation transactional by using a temporary variable first
    char *_tmp = (char *) realloc(input, (arrSize *= 2));

    // If the reallocation didn't go so well, inform the user and bail out
    if (!_tmp)
    {
      fprintf(stderr, "ERROR: Couldn't realloc memory!\n");
      return(-1);
    }

    // Things are looking good so far
    input = _tmp;
  }

  printf("\narrCount = %d; ch = %c; sizeof(ch) = %d\n", arrCount, ch, sizeof(ch));
  input[arrCount++] = ch;

  printf("&input[%d] = %p\n", arrCount-1, &input[arrCount - 1]);
  printf("input[%d] = %c\n", arrCount - 1, input[arrCount - 1]);
  if (ch == 'l') {
    break;
  }
}

Example output:

... $ ./db

Input is an array of 200 characters that takes up 200 bytes.

tl

arrCount = 0; ch = t; sizeof(ch) = 4

&input[0] = 0x827a008

input[0] = t

input[0] = t


arrCount = 1; ch = l; sizeof(ch) = 4

&input[1] = 0x827a00a

input[1] = l

input[1] = t

Segmentation fault

Something else that might be linked to this: I noticed if I inputted enough characters for my input array to get to index 399 / size 400, this error popped up as well:

*** glibc detected *** ./db: realloc(): invalid old size: 0x08a73008 ***

Solution

  • This is wrong, you're freeing the array you just allocated:

    input = _tmp;
    free(_tmp);
    

    You don't need the free at all - realloc does that for you.