0

guys I want to ask why am I constantly getting segfault with second fread inside of a while loop after checking jpeg header. first fread works perfectly going through first several 512bytes of card.raw. However entering in to while loop after header check, it crashes all the time whatever I try. First I tried malloc for image buffer and freed it before trying second fread which failed. Second, I tried appending output file using else if statements with only one fread function at the top which crashed also. Otherwise I tried several different methods whole weekend which I remember vaguely. Please help me to figure out any problem with my code. Thanks.

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

    int main(int argc, char *argv[])
    {
    FILE *inptr = fopen(argv[optind], "rb");
    if (inptr == NULL)
    {
        fprintf(stderr, "Could not open %s.\n", argv[optind]);
        return 1;
    }
    char fc[3];
    while (1)
    {
        uint8_t image[512];
        fread(image, 1, 512, inptr);
        int filecounter = 0;

        if (image[0] == 0xff && image[1] == 0xd8 && image[2] == 0xff &&
            image[3] >= 0xe0 && image[3] <= 0xef)
        {
            sprintf(fc, "%03i.jpg", filecounter);
            char *outfile = fc;
            FILE *outptr = fopen(outfile, "wb");

            if (outptr == NULL)
            {
                fclose(outptr);
                fprintf(stderr, "Could not create %s.\n", outfile);
                return 1;
            }
            filecounter++;
            int w = 0;

            while (w == 0)
            {
                fwrite(image, 1, 512, outptr);
                fread(image, 1, 512, inptr);
                for(int i = 0; i < 511; i++)
                {
                    if(image[i] == 0xff && image[i + 1] == 0xd9)
                    {
                        w = 1;
                        fwrite(image, 1, 512, outptr);
                        fclose(outptr);
                        break;
                    }
                }
            }
        }
        if(feof(inptr))
        {
            fclose(inptr);
            return 0;
        }
    }
}

1 Answer 1

0

This is a very subtle problem caused by a very small mistake, hidden somewhere that one wouldn't think to check. The problem is a data corruption issue. Data from one var is corrupting data in another place.

Look at the following code:

char fc[3];
while (1)
{
    ...
        sprintf(fc, "%03i.jpg", filecounter);
        char *outfile = fc;
        FILE *outptr = fopen(outfile, "wb");

The call to sprintf builds the output filename and stores it in fc. The problem here is that the file name is 8 chars (including the end of string marker) but fc only has 3 chars allocated to it.

C will allow the write to happen, without throwing an error. The result is that whatever data is next in physical memory will be overwritten. In this case, it looks like the adjacent variable that's being corrupted is the input file pointer inptr. It gets overwritten when fc is populated, so the next time inptr is accessed, it throws a seg fault.

BTW, the 4 lines for creating the file pointer can be simplified to 3 lines. There's no need for an intermediate var:

        char outfile[8];
        sprintf(outfile, "%03i.jpg", filecounter);
        FILE *outptr = fopen(outfile, "wb");

There appear to be other issues in the code, but that would be for a new question.

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

2
  • Thanks! I never even thought about the char variable. :)
    – Hyukjae Ko
    Jun 14, 2021 at 23:28
  • It's a subtle problem, but it seems to pop up on this pset a lot. I learned it the hard way years ago. Lesson to learn here: When you get phantom problems that defy explanation, run debug and watch all the vars when they change. Make sure that the change is expected and fully explainable.
    – Cliff B
    Jun 14, 2021 at 23:32

You must log in to answer this question.

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