notaorb
notaorb

Reputation: 2180

Writing out a binary structure to file, unexpected results?

I'm trying to write out a packed data structure to a binary file, however as you can see from od -x below the results are not expected in their ordering. I'm using gcc on a 64-bit Intel system. Does anyone know why the ordering is wrong? It doesn't look like an endianness issue.

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

struct B {
     char a;
     int b;
     char c;
     short d;
} __attribute__ ((packed));

int main(int argc, char *argv[])
{
     FILE *fp;
     fp = fopen("temp.bin", "w");

     struct B b = {'a', 0xA5A5, 'b', 0xFF};

     if (fwrite(&b, sizeof(b), 1, fp) != 1)
          printf("Error fwrite\n");

     exit(0);
}

ASCII 61 is 'a', so the b.a member. ASCII 62 is 'b', so the b.c member. It's odd how 0xA5A5 is spread out over the sequence.

$ od -x temp.bin 
0000000 a561 00a5 6200 00ff
0000010

Upvotes: 3

Views: 99

Answers (2)

John Kugelman
John Kugelman

Reputation: 361605

od -x groups the input into 2-byte units and swaps their endianness. It's a confusing output format. Use -t x1 to leave the bytes alone.

$ od -t x1 temp.bin
0000000 61 a5 a5 00 00 62 ff 00
0000010

Or, easier to remember, use hd (hex dump) instead of od (octal dump). hd's default format doesn't need adjusting, plus it shows both a hex and ASCII dump.

$ hd temp.bin
00000000  61 a5 a5 00 00 62 ff 00                           |a....b..|
00000008

Upvotes: 8

Andrew Henle
Andrew Henle

Reputation: 1

od -x writes out two little-endian bytes. Per the od man page:

-x     same as -t x2, select hexadecimal 2-byte units

So

0000000 a561 00a5 6200 00ff

is, on disk:

0000000 61a5 a500 0062 ff00

Upvotes: 2

Related Questions