Search code examples
c++segmentation-faultfstream

Segmentation fault when reading binary file


I am trying to read data from an existing binary file, but all I got is a segmentation fault. I thought that it might be come from the struct, so I used a temporary array where I try to fill in the values, but the problem seems to come from the ifstream read function. Can anybody help me to solve this problem?

bool RestoreRaspberry::RestorePhysicalAdress(TAddressHolder &address) {
    mPRINT("now i am in restore physical address\n");
    /*
    if (!OpenFileForRead(infile, FILENAME_PHYSICALADDRESS)){
        printf("\nRestoreUnit: Error open file Restore Physical Address\n");
        return false;
    }
    */
    ifstream ifile;
    ifile.open(FILENAME_PHYSICALADDRESS, ios_base::binary | ios_base::in);
    if (!ifile.is_open())
    {
        printf("\nRestoreUnit: Error open file Restore Physical Address\n");
        return false;
    }

    printf("\nRestoreUnit: now trying to read it into adress structure\n");

    uint8 arr[3];
    //the problem occurs right here
    for (int i = 0; i < cMAX_ADRESS_SIZE || !ifile.eof(); i++) {
        ifile.read(reinterpret_cast<char *>(arr[i]), sizeof(uint8)); 
    }

#ifdef DEBUG
    printf("physical address from restoring unit: ");
    /*
    printf("%#x ", address.Address[0]);
    printf("%#x ", address.Address[1]);
    printf("%#x \n", address.Address[2]);
    */
    printf("%#x", arr[0]);
    printf("%#x ", arr[1]);
    printf("%#x \n", arr[2]);
#endif
ifile.close();
    if (!ifile){//!CloseFileStream(infile)){
        printf("\nRestoreUnit: Error close file Restore Physical Address\n");
        return false;
    }

} 

Solution

  • It's hard to tell since you didn't provide a compilable example, but from the looks of it the problem is here:

    ifile.read(reinterpret_cast<char *>(arr[i]), sizeof(uint8));
    

    You are reinterpreting a uint8 as a char *. This means that whatever is being held in arr[i] (which is undefined since you didn't initialize it) is being interpreted as an address to which values will be read. I believe this is what you were intending:

    ifile.read(reinterpret_cast<char *>(&arr[i]), sizeof(uint8));
    

    Or, arguably more clearly:

    ifile.read(reinterpret_cast<char *>(arr + i), sizeof(uint8));
    

    You should also change the loop conditional to use &&; right now, if the file has more than 3 bytes in it, you will overrun arrarray and possibly segfault there as well:

    for (int i = 0; i < cMAX_ADRESS_SIZE && !ifile.eof(); i++) {