Search code examples
cdynamic-memory-allocation

segmentation fault during realloc


First allow me to apologize for the formatting and the difficult code. I am new to C and Stack. Most of the messy code here are probably irrelevant to the problem but necessary to include for the context.

The code below runs into segmentation fault after the first call to realloc (noted in the comments). return_file->target_line is simply a 3D array, i is an element count of the first dimension of the 3D array. So I'm calling realloc on it to store additional 2D arrays (of type char **).

NULL returns of memory allocations were purposely omitted b/c the developement protocol specifically stated all memory allocations will be successful (which I have a doubt of).

I'm using my own memory check program. The error code I get is:

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7ac63fb in reallochook () from /lib64/libc.so.6

I have looked at it for a very long time but can't seem to find what the problem is.

Mockfile *read_mockfile(const char filename[]) {
  Mockfile *return_file = NULL;
  FILE *input;

  if(filename != NULL && (input = fopen(filename, "r")) != NULL) {
    char **split_tmp, line[MAX] = {0};

    return_file = malloc(sizeof(Mockfile));
    return_file->rule_count = 0;

    /*read lines*/
    while(fgets(line, MAX, input) != NULL){
      if(line[0] != '#' && line[0] != '\n'){
        int j, i = return_file->rule_count;
        split_tmp = split(line);

        if(line[0] != '\t'){
          j = 0;


          /*target line. Realloc every string in three steps. Segementation fault occurs after this line below.*/
          return_file->target_line = realloc(return_file->target_line, (i + 1) * sizeof(char **));

          while(split_tmp[j] != NULL){
            return_file->target_line[i] = realloc(return_file->target_line[i], (j + 1) * sizeof(char *));
            return_file->target_line[i][j] = malloc(strlen(split_tmp[j]) + 1);
            strcpy(return_file->target_line[i][j], split_tmp[j]);
            j++;
          }
          return_file->target_line[i] = realloc(return_file->target_line[i], (j + 1) * sizeof(char *));
          return_file->target_line[i][j] = NULL;
        } else {
          j = 0;

          /*action line. Allocate every string in three steps*/
          return_file->action_line = realloc(return_file->action_line, (i + 1) * sizeof(char **));

          while(split_tmp[j] != NULL){
            return_file->action_line[i] = realloc(return_file->action_line[i], (j + 1) * sizeof(char *));
            return_file->action_line[i][j] = malloc(strlen(split_tmp[j]) + 1);
            strcpy(return_file->action_line[i][j], split_tmp[j]);
            j++;
          }
          return_file->action_line[i] = realloc(return_file->action_line[i], (j + 1) * sizeof(char *));
          return_file->action_line[i][j] = NULL;

          return_file->rule_count++;
        }
      }
    }
    fclose(input);
  }
  return return_file;
}

Solution

  • realloc() expects its first argument to point to a valid block of memory or NULL, so after malloc() you should initialise:

    return_file = malloc(sizeof(Mockfile));
    return_file->rule_count = 0;
    return_file->target_line = NULL; /* Add this */
    

    This should resolve that crash.

    Note also that foo = realloc(foo, N); is a bug, as realloc() can return NULL, so you need to handle that for completeness.