Search code examples
c++freadfseek

Segmentation fault in comparing the second byte of two files


I was testing the commands fread() and fseek, and I made a programme to compare the second byte of both the programme. The programme gave segmentation fault at the line indicated (the last fread()).

int main(int argc, char** argv)
{
    FILE *file1, *file2;
    long size1, size2;
    long size1a, size2a;
    char *name1, *name2;
    char *temp1, *temp2;

    if (argc != 3)
    {
        cout<<"Enter two file names"<<endl;
        exit(1);
    }

    name1 = argv[1];
    name2 = argv[2];

    //open files
    file1 = fopen(name1, "r");
    file2 = fopen(name2, "r");

    //get file size
    fseek(file1, 0, SEEK_END);
    size1 = ftell(file1);
    rewind(file1);

    fseek (file2,0,SEEK_END);
    size2 = ftell(file2);
    rewind(file2);

    fseek(file1,1,SEEK_SET);
    fseek(file2,1,SEEK_SET);
    cout<<"1"<<endl; //----cout worked
    fread(temp1,1,1,file1);
    cout<<"2"<<temp1<<endl; //---cout worked. 2nd byte of file1 was printed.
    fread(temp2,1,1,file2); //SEGMENTATION FAULT AT THIS LINE

    if(*temp1==*temp2)
        cout<<"same"<<endl;
    else
        cout<<"different"<<endl;    

    return 0;
}

Although I corrected the programme by defining

char temp1, temp2;

and writing

fread(&temp1,1,1,file1);
fread(&temp2,1,1,file2);

I still do not know what gave the seg fault at the second fread whereas the first one ran correctly. What might be the reason for the segmentation fault?


Solution

  • 1) open files in binary mode `fp = fopen(name, "rb");

    2) check the result of file openning if(fp != NULL)

    3) allocate memory for data: char *temp1; is not enough, it is just pointer, you need something like:

      temp = (char*) malloc(sizeof(char) * N); // N number of bytes
    

    EDIT:

    4) do not forget to close the file (even if it is not a cause of segmentation fault).

    I just make changes and the following code works without problems:

    #include <stdio.h>
    #include <stdlib.h>
    #include <iostream>
    using namespace std;
    
    int main(int argc, char** argv)
    {
        FILE *file1, *file2;
        long size1, size2;
        long size1a, size2a;
        long greater;
        char *name1, *name2;
        char *temp1, *temp2;
        // memory allocation (two lines added)
        temp1 = (char*) malloc(sizeof(char));
        temp2 = (char*) malloc(sizeof(char));
    
        if (argc != 3)
        {
            cout<<"Enter two file names"<<endl;
            exit(1);
        }
    
        name1 = argv[1];
        name2 = argv[2];
    
        //open files
        file1 = fopen(name1, "rb");
        if(file1 == NULL)
        {
            cout<<"File "<< name1 << " cannot be read" <<endl;
            exit(1);
        }
        file2 = fopen(name2, "rb");
        if(file2 == NULL)
        {
            cout<<"File "<< name2 << " cannot be read" <<endl;
            exit(1);
        }
        //get file size
        fseek(file1, 0, SEEK_END);
        size1 = ftell(file1);
        rewind(file1);
    
        fseek (file2,0,SEEK_END);
        size2 = ftell(file2);
        rewind(file2);
    
        if(size1>size2) greater = size1;
        else greater = size2;
    
        fseek(file1,1,SEEK_SET);
        fseek(file2,1,SEEK_SET);
        cout<<"1"<<endl; //----cout worked
        fread(temp1,1,1,file1);
        cout<<"2"<<temp1<<endl; //---cout worked. 2nd byte of file1 was printed.
        fread(temp2,1,1,file2); //SEGMENTATION FAULT AT THIS LINE
    
        if(*temp1==*temp2)
            cout<<"same"<<endl;
        else
            cout<<"different"<<endl;    
    
        fclose(file1);
        fclose(file2);
        // memory de-allocation (two lines added)
        free(temp1);
        free(temp2);
        return 0;
    }
    

    EDIT2:

    5) de-allocate memory after usage (two more lines added)