0

I am new to C and recently i have been working on a program whereby i am reading a stream of 512 bytes from a file using fread into a array and then after checking for certain conditions in that stream of bytes i am writing the stream of bytes into a new file using fwrite.
The code snippet for the same is

    unsigned char buffer[512];
    FILE *fp = fopen("file.name","r");

    if(fp == NULL)
    {
        perror("Error opening the file\n ");
        fclose(fp);
        return -1;
    }

    while(fread(&buffer, sizeof(buffer), 1 , fp) == 1) //my program works fine for both &buffer and only buffer
    {
          //Do something
    }

The definition of fread is:

    size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream)

Here ptr is the pointer to a block of memory where the read bytes will be stored.

I have defined buffer to be a character array and hence only passing buffer as the first parameter should have been enough as it is a pointer but the program works fine even when &buffer is being provided. The same is happening with fwrite as well. Now if buffer is the pointer then &buffer is the address of the pointer and should not have the same result as that of a pointer but it actually does, so why does the function work properly with both the different parameters?

  • They point to the same address. – rslemos Jul 03 '14 at 22:00
  • 1
    `&buffer` is *not* the "address of the pointer". That statement doesn't even make sense. There is no "the pointer". – Kerrek SB Jul 03 '14 at 22:02
  • 1
    Also note that your function will only read blocks of 512 bytes. If your file size isn't a multiple of that, you won't be able to read the remainder. – Kerrek SB Jul 03 '14 at 22:03
  • Best answer from the link Jon cites: "That's because the array name (my_array) is different from a pointer to array. It is an alias to the address of an array, and its address is defined as the address of the array itself." – FoggyDay Jul 03 '14 at 23:38

1 Answers1

3

In C, any data-pointer type is implicitly convertible to void*:

  • buffer designates the array. It is not a pointer. Arrays are in nearly all contexts converted to a pointer to their first elements though.
  • &buffer this is one of the exceptions, so here we have a pointer to said array instead.

Anyway, you probably want to do this instead:

size_t count;
while((count = fread(buffer, 1, sizeof(buffer), fp)) > 0)

Why?

  • Because you want to read all the data, and not miss the final partial block.
  • On an interactive device you want to act on the data as early as possible, not waiting until a full sizeof(buffer) block is done.
Deduplicator
  • 44,692
  • 7
  • 66
  • 118