0

My code for Recover is passing all the tests in Check50 except for the final one on memory errors. When I run valgrind ./recover I get this:

enter image description here

When I look into the details of why I'm not passing Check50 I see the following error information:

running valgrind --show-leak-kinds=all --xml=yes --xml-file=/tmp/tmpf5qa2h45 -- ./recover card.raw...
checking that program exited with status 0...
checking for valgrind errors...
Invalid read of size 4: (file: recover.c, line: 64)
Invalid read of size 8: (file: recover.c, line: 64)
Invalid write of size 8: (file: recover.c, line: 64)
Invalid write of size 4: (file: recover.c, line: 64)
Invalid read of size 4: (file: recover.c, line: 74)
Invalid read of size 8: (file: recover.c, line: 74)
Invalid write of size 8: (file: recover.c, line: 74)
Invalid write of size 4: (file: recover.c, line: 74)
Invalid read of size 4: (file: recover.c, line: 55)
Invalid read of size 1: (file: recover.c, line: 55)
Invalid read of size 8: (file: recover.c, line: 55)
Invalid write of size 8: (file: recover.c, line: 55)
Invalid free() / delete / delete[] / realloc(): (file: recover.c, line: 55)
Invalid read of size 4: (file: recover.c, line: 81)
Invalid read of size 1: (file: recover.c, line: 81)
Invalid read of size 8: (file: recover.c, line: 81)
Invalid write of size 8: (file: recover.c, line: 81)
Invalid free() / delete / delete[] / realloc(): (file: recover.c, line: 81)
23,128 bytes in 49 blocks are still reachable in loss record 1 of 1: (file: recover.c, line: 61)

My code for .recover is here:

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

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

    // Open card.raw file
    FILE *raw_file = fopen(argv[1], "r");

    // Create variable for 512-byte block size
    int BLOCK_SIZE = 512;

    // Create empty array of bytes for reading jpeg blocks
    uint8_t buffer[512];

    // Create counter for jpeg file names
    int counter = 0;

    // Flag for first jpeg
    int first_jpeg = 0;

    // Allocate memory for new filename
    char *filename = malloc(8);

    // Name first jpeg file
    sprintf(filename, "%03i.jpg", counter);

    // Open first file for first jpeg
    FILE *img = fopen(filename, "w");

    // Execute until the end of the card.raw file
    while (fread(buffer, 1, BLOCK_SIZE, raw_file) == BLOCK_SIZE)
    {
        // Check for start any jpeg
        if (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && (buffer[3] & 0xf0) == 0xe0)
        {
            // If this is the first jpeg
            if (counter == 0)
            {
                // Write jpeg to file
                fwrite(buffer, sizeof(int8_t), 512, img);
                first_jpeg = 1;
                counter++;
            }
            else
            {
                // Close old jpeg file
                fclose(img);

                // Name new jpeg file
                sprintf(filename, "%03i.jpg", counter);

                // Open new file
                fopen(filename, "w");

                // Write jpeg to file
                fwrite(buffer, sizeof(int8_t), 512, img);
                counter++;
            }
        }
        // If not the start of a new jpeg file
        else
        {
            // Only continue writing if have already found first jpeg
            if (first_jpeg == 1)
            {
                fwrite(buffer, sizeof(int8_t), 512, img);
            }
        }

    }

    // Close last open image
    fclose(img);

    // Close open files
    fclose(raw_file);

    // Free allocated memory for jpeg filename
    free(filename);
}

I'd love to understand where I'm going wrong on the memory side if anyone is able to spot my error!

1 Answer 1

0

The code creates the correct number of output files, but they're all 0 bytes in size except for the first one [EDIT] in my IDE environment - see below.

Take a look at this line of code (line 61):

            // Open new file
            fopen(filename, "w");

Now, compare it to line 36. See anything significantly different?

[EDIT: following some further research] Interestingly, this may or may not result in the files being empty. Under certain conditions, the code will successfully write to the output files correctly, but sometimes not. The results are unpredictable. (In my IDE, it failed. On yours and others, it succeeds.) However, it always results in the valgrind errors.

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

2
  • In some circumstances, the files are created correctly, so check50 isn't broken in that respect.
    – curiouskiwi
    Commented Aug 19, 2022 at 6:47
  • Yeah I was just about to say the same thing. When I run the code it creates the 50 jpegs and I am able to open them and view the files. So they don't appear to be empty.
    – getsendy
    Commented Aug 19, 2022 at 15:09

You must log in to answer this question.

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