Search code examples
cbus-error

Why do I get bus-error with an unused FILE pointer?


I am trying to write a function to read out 2 files with fgets and print them to stdout:

void merge_files(){
    FILE *in1, *in2, *out;
    char *inName1 = "Text_4_input1.txt";
    char *inName2 = "Text_4_input2.txt";
    char *buffer;
    int n = 100;
    if ( (in1 = fopen (inName1, "r")) == NULL ) {
       printf ("Can't open %s for reading.\n", inName1);
    }
    
    if ( (in2 = fopen (inName2, "r")) == NULL ) {
       printf ("Can't open %s for reading.\n", inName2);
    }
    while (fgets (buffer, n, in1 ) !=  NULL)
    {
        fputs (buffer, stdout);
        if ( fgets (buffer, n, in2) != NULL )
        {
            printf ("a");
            fputs (buffer, stdout);
        }
    }
    while (fgets (buffer, n , in2 ) !=  NULL )
    
        fputs (buffer, stdout);
        
    fclose (in1);
    fclose (in2);
}

I always get bus error when running it, and figured out that my FILE *out is never used. If I remove it from my code, then it will work as expected. Why?


Solution

  • You declare a buffer pointer:

    char *buffer;
    

    but you don't point it at anything. For a small-ish buffer that is of a constant fixed size, you might want to change this to:

    #define BUFF_SIZE 100
    ...
    char buffer[BUFF_SIZE];
    

    Get rid of the variable n. Read the data with:

    while (fgets (buffer, BUFF_SIZE, in1 ) !=  NULL)
    

    Alternatively, if you might have very large buffers and don't want to consume stack for it, you should allocate a buffer from the heap. Keep the variable n. Then:

    int n = 100;
    char *buffer = malloc(n);
    if (buffer == NULL) {
      // print error and probably exit
    }
    

    Then, at the end of the function:

    free(buffer);
    

    This will fix your immediate problem. But don't forget what some of the comments have also said, like Weather Vane pointing out that you detect fopen errors but continue execution. You should exit the program, or at least return a bad status to your caller.