0

I am trying to solve why I get a segmentation fault in my code "recover". It's right at the end of the file. I solved the pset4 by trying different solutions. However, I don't understand why my following version didn't work this way.

It seems that I can't use a general If-else-statement but have to use an if - if else-statement intead for the code to work properly. I put the version causing a segmentation fault below and added in the comment above the working solution.

    int main(int argc, char *argv[])
    {
    if (argc != 2)
    {
        printf("Usage: ./recover image\n");
        return 1;
    }

    FILE *input = fopen(argv[1], "r");
    if (input == NULL)
    {
        printf("File cannot be opened\n");
        return 1;
    }

    // create Buffer of size 512 with 8-bits integer
    typedef uint8_t BYTE;

    //initialize variables
    BYTE buffer[512];

    int counter = 0;

    char *filename = malloc(sizeof(char) * 8);

    FILE *img = NULL;

    bool jpeg_already_found = false;

    //loop over input as long as fread returns 1
    while (fread(&buffer, 512, 1, input) == 1)
    {
        //check for beginning of .jpeg
        if (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && (buffer[3] & 0xf0) == 0xe0)
        {

            //initialize first block of a the first .jpeg-file
            if (jpeg_already_found == false)
            {
                sprintf(filename, "%03i.jpg", counter);
                img = fopen(filename, "w");
                fwrite(&buffer, 512, 1, img);

                counter++;
                jpeg_already_found = true;

            }

            //code if new .jpeg is found - hence a new picture should start
            else if (jpeg_already_found == true)
            {
                fclose(img);

                sprintf(filename, "%03i.jpg", counter);
                img = fopen(filename, "w");
                fwrite(&buffer, 512, 1, img);

                counter++;
            }

        }
        //Problem occurs here:when I use "else if (img_already_found == true) it's working properly. 

        else
        {
            fwrite(&buffer, 512, 1, img);
        }


    }

    //close and free

    free(filename);
    fclose(img);
    fclose(input);
}

Thanks for help.

0

You've already answwered your own question, but just haven't connected the dots. The pset spec says that the input file contains garbage data before the first file. Think about what happens with the first data block. No output file has ever been opened.

Now, think about the process under those conditions. The first data block is read, no signature is found, and the code continues forward until it finds this:

else
{
    fwrite(&buffer, 512, 1, img);
}

The program tries to process this fwrite. But, since no output file has been opened, the pointer points at nothing. The attempt to do an fwrite fails and the result is a seg fault.

That's why it works perfectly when you change it to an else if statement. The code is then checking to see if the output file has been opened.

If this answers your question, please click on the check mark to accept. Let's keep up on forum maintenance. ;-)

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .