I've been stuck with this one for a little while. Through debugging I found out that my problem is probably in the size parameter I'm trying to pass to fread() in line 33 (start of the while loop). However I have no idea what I'm doing wrong.

I thought every block was supposed to be 512 bytes and that sizeof(BYTE) would be enough to specify it. I also tried using sizeof(buffer) and telling the program to only read that size one time.

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

typedef uint8_t BYTE;

int main(int argc, char *argv[])
    // Ensures correct usage
    if (argc != 2)
        printf("Usage: ./recover image\n");

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

    // Checks if file exist
    if (file == NULL)
        printf("It wasn't possible to open the file\n");
        return 1;

    char filename[7];
    int jpg_count = 0;
    BYTE buffer[512];
    FILE *img = NULL;

    // Repeats while fread() is able to read 512 bytes into buffer
    while (fread(buffer, sizeof(BYTE), 512, file) == 512)
        // Checks if the first 4 bytes are the start of a jpg
        if ((buffer[0] == 0xff) && (buffer[1] == 0xd8) && (buffer[2] == 0xff) && ((buffer[3] & 0xf0) == 0xe0))
            // If it's not the first jpg, close the last one
            if (jpg_count != 0)

            // Declares the name of the file
            sprintf(filename, "%03i.jpg", jpg_count);

            // Opens a new jpg
            img = fopen(filename, "w");

            // Checks if it was able to open file
            if (img == NULL)
                printf("It wasn't possible to create a new jpg\n");
                return 1;


        // If it's the first iteration, but isn't the start of jpg, you probably don't want to write what is there (you might get rick rolled =/)
        if (img != NULL)
            // Writes block
            fwrite(buffer, sizeof(BYTE), 512, img);

The terminal is always as follows:

~/pset4/recover/ $ ./recover card.raw

Fatal error: glibc detected an invalid stdio handle



At line 46, you write to the outside of filename declared at line 27. Here is the link that you can debug errors like this by yourself.

  Memory access error: writing to the outside of a memory space; abort execution.
  # Writing 1 bytes to 0xffe686b3 will clobber other memory-spaces.
  # The memory-space-to-be-written (start:0xffe686ac, size:7 bytes) is bound to 'filename' at
  #    file:/recover.c::27, 10
  #  0xffe686ac               0xffe686b2
  #  +------------------------------+
  #  |the memory-space-to-be-written|......
  #  +------------------------------+
  #                                  ^~~~~~~~~~
  #        the write starts at 0xffe686b3 that is right after the memory-space end.
  # Stack trace (most recent call first) of the write.
  # [0]  file:/musl-1.1.10/src/stdio/vsnprintf.c::40, 9
  # [1]  file:/musl-1.1.10/src/stdio/vsprintf.c::6, 9
  # [2]  file:/musl-1.1.10/src/stdio/sprintf.c::19, 8
  # [3]  file:/recover.c::46, 13
  # [4]  [libc-start-main]
  • I'm not sure how to fix it. I thought that maybe I could assign filename to NULL after I finished using it, but that didn't work because it's not a pointer. – Henrique Baesa May 25 '20 at 0:20
  • you can make filename larger by declaring it as char filename[16] and try it again. Your code might have other errors. Please accept my answer if it pointed out the cause. – stensal May 25 '20 at 0:22
  • Now it works perfectly! Thank you! Was that error occurring because I was forgetting about the "\0" in the end of the string or something else? – Henrique Baesa May 25 '20 at 0:33
  • No, sprintf will automatically append '\0', your filename array is just too small. – stensal May 25 '20 at 0:38

You must log in to answer this question.

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