Search code examples
ccs50recover

Need advice pset4 recover. Tried for a week and still getting segmentation fault


Output:

:( recovers 000.jpg correctly
    failed to execute program due to segmentation fault
:( recovers middle images correctly
    failed to execute program due to segmentation fault
:( recovers 049.jpg correctly
    failed to execute program due to segmentation fault

Code:

#include <stdio.h>
#include <stdint.h>

int main(int argc, char *argv[])
{
    if (argc != 2) //to make sure that accept exactly one command-line argument
    {
        printf("Usage: ./recover key\n");
        return 1;
    }

    FILE *infile = fopen(argv[1], "r"); //open the file card.raw and creating a new file called f in read format
    if (infile == NULL)//if file cannot open then print below if can open just continue
    {
        printf("Cannot open file\n");
        return 2;
    }

    FILE *img; //img is the output
    int jpeg_counter = 0; // to count the no. of jpeg files
    uint8_t buffer[512]; //cos 512 bytes and the buffer is the temporary storage 
    char filename[8];


    while (fread(buffer, sizeof(buffer), 1, infile) == 512)
        //continue doing this loop if the while conditions are true. to repeat until end of card.like while the file you reading is true,
    {
        if (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && (buffer[3] & 0xf0) == 0xe0)
            //removing last 4 bits of the 8 bits, only looking at they first 4 which is e. setting all to 0
            //if start of new jpeg with above conditions 
        {
            if (jpeg_counter != 0) // telling them that you previously found jpeg
            {
                fclose(img);//else if never find before, tell them now that you have found it by making it true
            }

            sprintf(filename, "%03i.jpg", jpeg_counter); //%03i means print an integer with 3 digits
            jpeg_counter ++;
            img = fopen(filename , "w"); //open the new file w for writting 
            if (img == NULL) //see if can remove this
                return 3;
            fwrite(buffer, sizeof(buffer), 1, img);// writing new output file

        }    
        if (jpeg_counter != 0)
            fwrite(buffer, sizeof(buffer), 1, img);
    } 
    fclose(infile);
    fclose(img);
    return 0;
}

Solution

  • the segfault is cased by fclose(img) and img is an invalid FILE pointer. The problem is your while loop condition is never true and the loop is never taken. Your fread will never return 512, it returns 1 on a success read. I have fixed the loop condition for you and added some printfs to print out more information so you have a better understanding of what happens. Here is a link of the fixed code in our cloud IDE, you can use it to debug segfault in the future.