0

CS50 NEWBIE here. Program successfully compiles but I keep getting a segmentation fault error when trying to run it. After some debugging, I think the problem has something to do with trying to close a null file--fclose(output_pointer). How can I get around this? If thats not the issue, what else could produce this error?

Appreciate any help, thanks!

// code start

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <cs50.h>
#define block_size 512



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

char* infile = argv[1];
//opening new file and assigning it a pointer
    FILE *in_pointer = fopen(infile, "r");
    if (in_pointer == NULL)
    {
        printf("Image cannot be opened for reading \n");
        return 1;
    }

    //declaring variables
        typedef uint8_t BYTE;
        BYTE buffer[block_size];
        bool first_jpeg = false;
        int jpeg_count = 0;
        FILE* output_pointer = NULL;


    //repeat until end of card

while (true)
    {
    size_t bytesread = fread(buffer, sizeof(BYTE), block_size, in_pointer);

        // break when bytesread is 0
        if (bytesread == 0 && feof(in_pointer))
            {
                break;
            }
        // checking if JPEG

        bool jpeg_image= buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && (buffer[3] & 0xf0) == 0xe0;

            if (jpeg_image && first_jpeg == false)
                {
                     first_jpeg=true;
                }
            if (jpeg_image && output_pointer != NULL)
                 {
                     fclose(output_pointer);
                 }
            if (jpeg_image && first_jpeg == true)
                 {
                //Printing a file name to the file name string for JPEGS
                 char filename[10];
                 sprintf(filename, "%03i.jpg", jpeg_count);
                 // opening the file to be able to write in to it. Returns file pointer to it.
                  output_pointer = fopen(filename, "w");
                  fwrite(buffer,sizeof(BYTE),block_size, output_pointer);
                 jpeg_count++;
                }

if (jpeg_image == 0)
        {
         fwrite(buffer,sizeof(BYTE),block_size, output_pointer);
           fclose(output_pointer);
        }
    //close any remaining file

}
 fclose(in_pointer);
 return 0;
}
2

That fact that a program compiles does not guarantee that it will work, only that it doesn't have any obvious syntax or similar issues. It's just an early step in the process.

Your instincts are correct, the code is trying to write to or close a file pointer that's set to null.

The seg fault problem lies in this code:

if (jpeg_image == 0)
    {
     fwrite(buffer,sizeof(BYTE),block_size, output_pointer);
       fclose(output_pointer);
    }

The if statement is to detect when a signature was NOT found, and to write the data block to the currently open output file. However, before the first signature is found, the data is garbage and is supposed to be discarded.

The problem is that this code will attempt to write the data block out before the first file is opened, i.e., while output_pointer == NULL. That triggers a seg fault.

Following this is another problem. The fclose call will close any opened output file after the first (signature) data block is written and the second (non-signature) block is written. When the third block is processed, the file was closed previously and another seg fault will be thrown.

There are more issues to follow, but I'll let you discover them and work on them first. ;-)

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

| improve this answer | |
  • Totally makes sense. I had not even thought of the possibility that the mem card could start with data blocks that do not include a JPEG signature! Genius. Thanks for the help! – Valerie Bryant Oct 20 at 17:30
  • Ummm.... it's in the description? – Cliff B Oct 20 at 18:57
0

I think trouble is there: bool jpeg_image == 0 .

you have tird step of loop, jpeg_image == 1, you write block in output_pointer.

fourth step, jpeg_image == 0, you write block in output_pointer and close it.

fifth step, jpeg_image == 0, you try to write block in output_pointer but it close.

| improve this answer | |

You must log in to answer this question.

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