Valgrind indicates I have 49 memory blocks left to close. Otherwise, the code satisfies check50. I'm thinking I need to nest the fclose functions within the loop, but I can't get it right. Thoughts?

int main(int argc, char *argv[])
//checks correct usage of command line arguments
    if (argc != 2)
        printf("Usage: ./recover IMAGE\n");
        return 1;

//returns a pointer at address input_file. fopen file at argv[1] and read it("r")
//essentially opening the file for reading
    FILE *input_file  = fopen(argv[1], "r");

//checking to ensure valid file
    if (input_file == NULL)
        printf("File could not be read.\n");
        return 2;

    //create an array with indices 512 bytes, 512 is the default FAT size for storing jpegs
    unsigned char buffer[512];
    //set image counter to 0
    int images = 0;
    //create a file pointer to output file, set to NULL
    FILE *output_file = NULL;
    //allocate needed memory for  *filename,  calulated as 8*size of char
    char *filename = malloc(8 * sizeof(char));

    //start iterating at buffer through intput_file, blocks of 512 bytes
    while (fread(buffer, sizeof(char), 512, input_file))
        //check indices of array buffer[] to see if they begin with JPEG marker
        if (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && (buffer[3] & 0xf0) == 0xe0)
            //if buffer[3]  plus 0xf0 == 0xe0 (converted to binary, 0x30 = 11100000 in binary, check pset4 recover notes)
            //thanks to youtube  cs50 guide  by Anvea for explination of mechanism
            // pointer to an array of char elements where resulting C string is stored, named a three digit decimal starting with i, i = int images
            sprintf(filename, "%03i.jpg", images);
            output_file = fopen(filename, "w"); //output_file is equal to function fopen(write from filename)
            images++; //(increases number of int = counted images)
        if (output_file != NULL) //if output file is not invalid
            fwrite(buffer, sizeof(char), 512, output_file); //(printsize = buffer, char size, 512 elements to write, pointer of output location)
    free(filename); //deallocates memory to ensure no leaks
    return 0;

Valgrind report:

==30211== Memcheck, a memory error detector
==30211== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==30211== Using Valgrind-3.18.1 and LibVEX; rerun with -h for copyright info
==30211== Command: ./recover card.raw
==30211== HEAP SUMMARY:
==30211==     in use at exit: 23,128 bytes in 49 blocks
==30211==   total heap usage: 103 allocs, 54 frees, 232,976 bytes allocated
==30211== 23,128 bytes in 49 blocks are still reachable in loss record 1 of 1
==30211==    at 0x4848899: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==30211==    by 0x4A086CD: __fopen_internal (iofopen.c:65)
==30211==    by 0x4A086CD: fopen@@GLIBC_2.2.5 (iofopen.c:86)
==30211==    by 0x1092EE: main (recover.c:45)
==30211== LEAK SUMMARY:
==30211==    definitely lost: 0 bytes in 0 blocks
==30211==    indirectly lost: 0 bytes in 0 blocks
==30211==      possibly lost: 0 bytes in 0 blocks
==30211==    still reachable: 23,128 bytes in 49 blocks
==30211==         suppressed: 0 bytes in 0 blocks
==30211== For lists of detected and suppressed errors, rerun with: -s
==30211== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

1 Answer 1


Got it!

Had to add the following RIGHT before sprintf() to ensure the previous iteration's output file was closed out

if (images > 0

hope this saves some headaches

You must log in to answer this question.

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