0

Can i please get some help with my recover code? i have rewritten it so many times but i still get a segmentation fault

i even unmalloc'd a few things but to no avail

// recovers deleted images
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

const int BUFFER_SIZE = 512;

int main(int argc, char *argv[])
{
    typedef uint8_t BYTE;
    // check command-line argument
    if (argc != 2)
    {
        printf ("Usage: ./recover image\n");
        return 1;
    }

    //open file and determine scaling factor
    FILE *file = fopen(argv[1], "r");
    if (file == NULL)
    {
        printf("Could not open file.\n");
        return 1;
    }

    int counter = 0;
    char filename[8];
    FILE *img = NULL;
    BYTE buffer[BUFFER_SIZE];

    // as long as fread returns 1
    while (fread(buffer, BUFFER_SIZE, 1, file) == 1)
    {
        // if jpeg header is found
        if (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && (buffer[3] & 0xf0) == 0xe0)
        {
            img = fopen(filename, "a");
            fwrite(buffer, BUFFER_SIZE, 1, img);

            // and it s the first jpeg header to be found
            if (counter == 0)
            {
                sprintf (filename, "%03i.jpg", counter);
                counter++;
            }
            // if a previous jpeg file have been opened
            else
            {
                // close that file then open a new jpeg file and write into it
                fclose(img);
                sprintf (filename, "%03i.jpg", counter);
                img = fopen(filename , "w");
                fwrite(buffer, BUFFER_SIZE, 1, img);
            }
        }
        // if fread doesnt return 1, continue writing into open file
        else
        {
            fwrite(buffer, BUFFER_SIZE, 1, img);
        }
    }

    fclose(img);
    fclose(file);
}

1 Answer 1

1

Glancing through the code, I see several issues. Overall, the code is having issues with output files not opened or opened incorrectly before trying to write to an output file.

First, think about what happens with the first block of data from the input file. The program spec says that there will be garbage data in the beginning of the input file. That means it won't have a signature (it's garbage data.) So, if the first block is garbage data with no signature, the code will drop down to the else clause following the if block that checks for a signature. Now, what happens? The code tries to write it out to a file. Since no file has been opened, it causes a seg fault. Maybe the code needs to check to see if a file is opened? Is there a var that counts the number of files that have been opened???? ;-)

Next, look at this entire section and think about what's being done and in what order!

    // if jpeg header is found
    if (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && (buffer[3] & 0xf0) == 0xe0)
    {
        img = fopen(filename, "a");
        fwrite(buffer, BUFFER_SIZE, 1, img);

        // and it s the first jpeg header to be found
        if (counter == 0)
        {
            sprintf (filename, "%03i.jpg", counter);
            counter++;
        }

When the first signature is found, here's what this code does. It attempts to open the output file before it has created a filename, so that's a problem. The other problem is that it tries to open for append, not for write. why??? If a file with that name already exists, it won't delete it, the code will only append to it. That's a problem.

Next, if it's the first file, the code will then create the filename, but nothing else. Maybe this is where the file should actually be opened?

This should get you past most of the major problems.

Some advice. When you get to a point where you're just not making progress, it's time to take a break for a couple hours, or better, overnight. Don't think about it, just set it aside. You're mind will subconsciously sort out some of the issues and you'll come back clearer headed.

Also, a good technique is to read through code line by line and actually explain, out loud, exactly what each line of code does. If you can't verbalize what everything does, there's a problem with the code. And, by saying it out loud, you'll often realize that something is missing or out of place. ;-)

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

2
  • Ah yes, it works now. i deleted the entire code within my while loop and rewrote it from scratch now it works perfectly. p.s i took two days off away from the problem, thanks for the advice
    – jeddah
    Commented Apr 11, 2022 at 11:20
  • Thanks @Cliff-b! My code was similar to the one from @jeddah and your explanation helped me to finally fix it.
    – Nebulonit
    Commented Aug 14, 2022 at 13:17

You must log in to answer this question.

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