A hex dump of a struct
Print every byte of a game save struct in hex and see the fields, the little-endian ints and the padding bytes nobody asked for.
What to look at
dump gets any block of memory as const unsigned char *, so it can read it one byte at a time. Before filling the struct, memset paints every byte aa, so any byte that still says aa afterwards is padding: space the compiler left so each int starts at an address that is a multiple of 4. Ints are stored little-endian: the lowest byte first, so 1000 (hex 3e8) shows up as e8 03 00 00. Moving the fields around changes the size.
Run it: bytes of a save file
Run it, read it, change it. Open in playground keeps your own copy.
#include <stdio.h>
#include <string.h>
#include <stddef.h>
struct save {
char slot; // 1 byte
int coins; // 4 bytes
char difficulty; // 1 byte
int level; // 4 bytes
};
struct save_packed {
int coins;
int level;
char slot;
char difficulty;
};
void dump(const char *label, const void *mem, int size) {
const unsigned char *b = mem;
printf("%s (%d bytes)\n", label, size);
for (int i = 0; i < size; i++) {
printf("%02x ", b[i]);
if (i % 8 == 7 || i == size - 1) {
printf("\n");
}
}
}
int main(void) {
struct save s;
memset(&s, 0xaa, sizeof s);
s.slot = 'A';
s.coins = 1000;
s.difficulty = 2;
s.level = 7;
dump("struct save", &s, sizeof s);
printf("offsets: slot %d, coins %d, difficulty %d, level %d\n",
(int)offsetof(struct save, slot), (int)offsetof(struct save, coins),
(int)offsetof(struct save, difficulty), (int)offsetof(struct save, level));
int wasted = 0;
const unsigned char *b = (const unsigned char *)&s;
for (int i = 0; i < (int)sizeof s; i++) {
if (b[i] == 0xaa) {
wasted++;
}
}
printf("padding bytes: %d\n\n", wasted);
struct save_packed p;
memset(&p, 0xaa, sizeof p);
p.coins = 1000;
p.level = 7;
p.slot = 'A';
p.difficulty = 2;
dump("struct save_packed", &p, sizeof p);
return 0;
}
Change it
- Set
coinsto-1and read the four bytes. Then try256and65536: which byte changes? - Add a
double best_time;field afterslotinstruct save. How many padding bytes appear now, and where? - Change
char slot;tochar name[5];and give it"Kai"withstrcpy. Can you spot the'\0'and the bytes after it? - Remove the
memsetlines. What do the padding bytes show now, and why can you not rely on them?