cpointersbuffercs50pointer-address

CS50 recover, when to use buffer and &buffer?


I am solved the pset4 recover in the CS50. Although I solved the problem, I am confuse between "buffer" & "&buffer". Please pay attention to "LINE AAAAA" & "LINE BBBBB".

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

// New type to store a byte of data
typedef uint8_t BYTE;

// Number of "block size" 512
const int BLOCK_SIZE = 512;

int main(int argc, char *argv[])
{
    // Check for 2 command-line arguments
    if (argc != 2)
    {
        printf("Usage: ./recover IMAGE\n");
        return 1;
    }
// Open card.raw file
FILE *input = fopen(argv[1],"r");

// Check for fail to open
if (input == NULL)
{
    printf("Couldn't open the file.\n");
    return 1;
}

// Read the first 4 bytes
BYTE buffer[BLOCK_SIZE];

// Count image
int count_image = 0;

// Assign NULL to output_file
FILE *output = NULL;

// Declare filename
char filename[8];

// LINE AAAAA
while (fread(buffer, sizeof(BYTE), BLOCK_SIZE, input) == BLOCK_SIZE)
{
    // Check first 4 bytes for JPEG file format
    if (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && (buffer[3] & 0xf0) == 0xe0)
    {
        // Only for first image, generate new filename and write into it
        if (count_image == 0)
        {
            // Generate a new file with sequence name
            sprintf(filename, "%03i.jpg", count_image);

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

            // LINE BBBBB
            fwrite (&buffer, sizeof(BYTE), BLOCK_SIZE, output);

            // Add filename counter
            count_image++;
        }

        // For subsequence new repeat JPG images
        // Close output file, generate new file, and write into it
        else if (count_image > 0)
        {
            // fclose current writing files
            fclose (output);

            // Generate a new file with sequence name
            sprintf(filename, "%03i.jpg", count_image);

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

            // LINE BBBBB
            fwrite (&buffer, sizeof(BYTE), BLOCK_SIZE, output);

            // Add filename counter
            count_image++;
        }
    }
    // Not fulfill the 4 bytes JPG condition, keep writing to the same filename
    else if (count_image > 0)
    {

    // LINE BBBBB
    fwrite (&buffer, sizeof(BYTE), BLOCK_SIZE, output);
    }
}
fclose(output);
fclose(input);

}

Question: Why do we use "&buffer" in LINE BBBBB instead of "buffer"?

I know LINE AAAAA is using "buffer" as BYTE buffer[BLOCK_SIZE] is an pointer or array. So "buffer" mean the location of the pointer.


Solution

  • When buffer is used, it often converts to the address of the first element. &buffer is the address of the array.

    Those 2 addresses will compare equal, yet have different types. When the type is important, use the matching one. Enable all warnings to help identify incorrect type usage.


    Since fread() use void *, either will work.

    Conceptually use buffer in this case to match the sizeof(BYTE) and BLOCK_SIZE.

    or

    fread(&buffer, sizeof buffer, 1, input) == 1)