0

I'm trying to dynamically allocate an array to read user input from the command line. It works 99/100 times, but if I type in a bunch of characters repeatedly I will sometimes get a segmentation fault error OR a double free or corruption(fasttop) error. This error is relatively hard to reproduce.

I'm pretty sure the error occurs because of the way I'm reallocating the array.

while(1){
        char *buf_in;               // Holds user keyboard input
        int cnt = 0, length = 0;    // cnt stores current read buffer size, length allows input into buf_in
        char ch;
        int buf_max = 64;           // Current buffer size. Dynamically allocated

        buf_in = malloc(buf_max * sizeof(char));
        if (buf_in==NULL){
            fprintf(stderr,"Error allocating memory!\n");
            exit(EXIT_FAILURE);
        }

        do{
            if (cnt > (buf_max/2)){
                cnt = 0;
                buf_max *= 2; // Double size of buffer
                printf("Doubling buffer: %d\n",buf_max);
                buf_in = realloc(buf_in,buf_max);
                if (buf_in == NULL){
                    fprintf(stderr,"Error re-allocating memory!\n");
                    exit(EXIT_FAILURE);
                }
            }
            /* Store line-by-line into buffer */
            ch = getc(stdin);
            buf_in[length] = ch;
            length++;
            cnt++;
        }while(ch != '\n');

        /* Handles different option arguments */
        processOptions(buf_in,&opt_n_inc);

        // stdout
        fprintf(stdout,"%s",buf_in);
        fflush(stdout);

        free(buf_in);
        buf_in=NULL;
    }
Jamie Yang
  • 13
  • 2

1 Answers1

1

Code appears to be attempting to print using "%s" an array of char and not a string. The null character '\0' termination is missing.

Also the problem may be manifesting itself in processOptions() as that function call does not pass the length of valid data.

buf_in[length] = ch;

// Add    
buf_in[length+1] = '\0';

...
processOptions(buf_in,&opt_n_inc);
fprintf(stdout,"%s",buf_in);

Note: infinite loop should getc(stdin) return EOF. Better to use

int ch = getc(stdin);
if (ch == EOF) break;
buf_in[length] = ch;
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
  • Thanks for the response. In this case, I'm trying to mimic the behavior of cat in bash. The infinite loop is meant to never terminate (only terminating on an interrupt signal from the keyboard). Do I have to free buffer on a termination signal? I'm worried about memory leaks. – Jamie Yang Jan 25 '15 at 01:34
  • @Jamie Yang 1) Code has 2 infinite loops: `while(1){` which is certainly the one in your comment. This answer points out a 2nd infinite loop. 2) Code does not need to free buffers on a "termination signal". When this program is done, the OS will get all its memory back. – chux - Reinstate Monica Jan 25 '15 at 02:22