Search code examples
cgcc

Why fwrite writes an excessive byte 00 at the first byte of file?


I wrote this piece of code :

#include <stdio.h>

int main(void)
{
    FILE * fp;
    int num[100];
    int number;

    fp = fopen("myfile.bin", "wb");
    
    for (number = 0; number < 100; ++number)
    {
        num[number] = number;
    }
    fwrite(num, 4, 100, fp);
    
    fclose(fp);
    
    return 0;
}

And fwrite writes down an excessive byte by value 00 in the first byte of file:

00 00 00 00 01

An int is only 4 bytes and the other bytes write normally but the first one, not.

What's wrong here? I tested by GCC, Clang and TCC, and read the file with Bless and Ghex. Same results.

I'm on Intel Pentium G3220, Debian GNU/Linux 12.5 and using GCC 12.2.0-3.


Solution

  • You seem to be reading the file wrongly. The hex output:

    00 00 00 00 01 00 00 00 02 00 00 00 ...
    

    is little endian (where the higher memory addresses carry the more significant parts of the value), with four bytes per integer:

    • 00 00 00 00 = 0.
    • 01 00 00 00 = 1.
    • 02 00 00 00 = 2.
    • and so on ...

    You seem to think it's:

    00 00 00 00 01 00 00 00 02 00 00 00 03 ...
    ?? |    1    | |    2    | |    3    |
    

    with an extraneous byte at the start but that is not the case. The fact that you have a four-hundred-byte file after writing one hundred four-byte integers should make that clear.

    The final four bytes will be, in your case, 63 00 00 00 and that's a little-endian 99, not 100. Your comment that you're starting with one is incorrect, the loop executes the body with values 0..99 inclusive:

    for (number = 0; number < 100; ++number) {
        num[number] = number;
    }
    

    C arrays are zero-based, not one-based, so 0..99 are the correct indexes for a 100-element array (and also the values that you are storing). If you do desire to store 1..100 inclusive in your array, you could instead use:

    for (number = 0; number < 100; ++number) {
        num[number] = number + 1;
    }
    

    The indexes are still 0..99 but the values are now 1..100.