0

When I ran the program, it said that there was a segmentation fault. I tried using debug50 to identify the source of the fault and it pointed to the line of code that I have bolded. I don't understand why that line of code caused a segmentation fault and why is it wrong to use it in my code. I used that line because the purpose of it is to read through the whole inptr file to scan for the blocks of JPEGs. What am I doing wrong here? Any help would be much appreciated, thank you :)

My code is as follows:

#include <cs50.h>
#include <stdio.h>

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

//Open memory card file
FILE *inptr = fopen(argv[1], "r");
if(argv[1] == NULL)
{
    fprintf(stderr, "File %s could not be opened.\n", argv[1]);
    return 2;
}

//Declaration of buffer array
int buffer[511];
int n = 0;

//Declaration of outfile
FILE *outptr = NULL;


//Repeat until end of card
char ch;
//Seg. fault is in this line
*while((ch = fgetc(inptr)) != EOF)*
{
    //Reading into memory card
    while((fread(buffer, 512, 1, inptr)) == 1)
    {
       //Check if start of new JPEG
       if(buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && (buffer[3] & 0xf0) == 0xe8)
       {
           fclose(outptr);

           //Naming the newly found JPEG
           char filename[10];
           sprintf(filename, "%03i.jpg", n);
           outptr = fopen(filename, "w");
           n++;

          //Writing JPEG to outfile
          fwrite(buffer, 512, 1, outptr);
       }
       else
       {
          //Writing JPEG to outfile
          fwrite(buffer, 512, 1, outptr);
       }
    }
}
//Closing of infile and outfile
fclose(inptr);
fclose(outptr);
}

1 Answer 1

2

Actually, the segfault is occurring later, at this line:

   else
   {
      //Writing JPEG to outfile
      fwrite(buffer, 512, 1, outptr);
   }                

There is a logic bug in the code. Remember that the pset instructions say that there is garbage data at the front of the file. The code reads in the first block, checks it for a valid signature, finds no signature, skips the first if statement and it's related code (that would have opened the output file), and tries to write the data to the current output file.

Unfortunately, the output file hasn't been opened yet because no signature has been found yet. The output file pointer is still NULL, so it segfaults.

As a side note, why do you have an fgetc and an fread, and in two nested while loops? It's going to be a problem. I'll let you figure out why. ;-)

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

3
  • Hey Cliff, thank you for the reply. My question is that why is a segmentation fault occuring at the fwrite line of code when I have already opened it few lines of code above this line at outptr = fopen(filename, "w"); ?
    – Prav Elan
    Commented Nov 28, 2017 at 10:24
  • Apart from that, I used the fgetc function because I cannot come up with another way to make sure that the whole card.raw file is scanned and read into the infile. If I'm only using while((fread(buffer, 512, 1, inptr)) == 1), would it read the whole card.raw file into the infile? I'm a bit confused here :(
    – Prav Elan
    Commented Nov 28, 2017 at 10:26
  • It didn't open. I should have been more specific about which fwrite is executing. I'll edit the answer accordingly. Also, you can use the return value from the fread call to determine if a block was read or not. What would cause a block not to be read?
    – Cliff B
    Commented Nov 28, 2017 at 10:56

You must log in to answer this question.

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