Search code examples
cfilememorymallocendianness

fwrite() in c writes bytes in a different order


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


int main(void)
{
    int *int_pointer = (int *) malloc(sizeof(int));

    // open output file
    FILE *outptr = fopen("test_output", "w");
    if (outptr == NULL)
    {
        fprintf(stderr, "Could not create %s.\n", "test_output");
        return 1;
    }

    *int_pointer = 0xabcdef;

    fwrite(int_pointer, sizeof(int), 1, outptr);

    //clean up
    fclose(outptr);
    free(int_pointer);

    return 0;
}

this is my code and when I see the test_output file with xxd it gives following output.

$ xxd -c 12 -g 3 test_output 
0000000: efcdab 00                    ....

I'm expecting it to print abcdef instead of efcdab.


Solution

  • Use htonl()

    It converts from whatever the host-byte-order is (endianness of your machine) to network byte order. So whatever machine you're running on you will get the the same byte order. These calls are used so that regardless of the host you're running on the bytes are sent over the network in the right order, but it works for you too.

    See the man pages of htonl and byteorder. There are various conversion functions available, also for different integer sizes, 16-bit, 32-bit, 64-bit ...

    #include <stdio.h>
    #include <stdlib.h>
    #include <arpa/inet.h>
    
    int main(void) {
        int *int_pointer = (int *) malloc(sizeof(int));
    
        // open output file
        FILE *outptr = fopen("test_output", "w");
        if (outptr == NULL) {
            fprintf(stderr, "Could not create %s.\n", "test_output");
            return 1;
        }
    
        *int_pointer = htonl(0xabcdef);  // <====== This ensures correct byte order
    
        fwrite(int_pointer, sizeof(int), 1, outptr);
    
        //clean up
        fclose(outptr);
        free(int_pointer);
    
        return 0;
    }