0

Can someone point out why this code is resulting in segmentation fault? It's a code for the 'recover' question in pset4, cs50.

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

typedef uint8_t BYTE;

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

    //opening input file.
    FILE *input = fopen(argv[1], "r");

    //checking if it was successful.
    if (input == NULL)
    {
        printf("Could not open file.\n");
        return 1;
    }

    //creating a buffer.
    BYTE buffer[512];

    //creating a pointer for file name.
    char name[8];

    //creating a counter.
    int counter = 0;

    //creating an output file.
    FILE *output = NULL;


    //looping and reading from input file into the buffer until reaching end of file.
    while (fread(&buffer, 512, 1, input))
    {
        //check conditions.
        if (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && (buffer[3] & 0xf0) == 0xe0)
        {
            if (!counter)
            {
                fclose(output);
            }

            sprintf(name, "%03i.jpg", counter);

            output = fopen(name, "w");

            counter++;
        }

        if (!counter)
        {
            fwrite(&buffer, 512, 1, output);
        }

    }

    fclose(input);
    if(counter > 0)
    {
        fclose(output);
    }
}
1

The code is seg faulting when it hits this code:

    if (!counter)
    {
        fwrite(&buffer, 512, 1, output);
    }

It fails on the first data block in buffer when it tries to execute the fwrite. That's because the first data block is garbage, no signature has been found yet, so no output file has been opened!

The underlying cause is the if statement. It's asking if NOT counter is true. On the first pass, counter is 0 or false, so NOT 0 is true, thus causing the call to fwrite. It should be if(counter).

As happens often, you may have conflated two practices. On one hand, a program returns 0 as an indicator that it ran successfully and a non-zero number as an error code. OTOH, the logic standard is that 0 (and only zero) is ALWAYS FALSE, and a non-zero number (even a negative) is ALWAYS interpreted as TRUE.

This will fix this problem. But, as soon as you fix that, there's another one lying in wait. You should be able to fix that one on your own. ;-)

You might also find this useful: Do YOU know how to find a seg fault?? Advice to new programmers

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 .