Basic question, but I expected this struct to occupy 13 bytes of space (1 for the char, 12 for the 3 unsigned ints). Instead, sizeof(ESPR_REL_HEADER)
gives me 16 bytes.
typedef struct {
unsigned char version;
unsigned int root_node_num;
unsigned int node_size;
unsigned int node_count;
} ESPR_REL_HEADER;
What I'm trying to do is initialize this struct with some values and write the data it contains (the raw bytes) to the start of a file, so that when I open this file I later I can reconstruct this struct and gain some meta data about what the rest of the file contains.
I'm initializing the struct and writing it to the file like this:
int esprime_write_btree_header(FILE * fp, unsigned int node_size) {
ESPR_REL_HEADER header = {
.version = 1,
.root_node_num = 0,
.node_size = node_size,
.node_count = 1
};
return fwrite(&header, sizeof(ESPR_REL_HEADER), 1, fp);
}
Where node_size
is currently 4 while I experiment.
The file contains the following data after I write the struct to it:
-bash$ hexdump test.dat
0000000 01 bf f9 8b 00 00 00 00 04 00 00 00 01 00 00 00
0000010
I expect it to actually contain:
-bash$ hexdump test.dat
0000000 01 00 00 00 00 04 00 00 00 01 00 00 00
0000010
Excuse the newbiness. I am trying to learn :) How do I efficiently write just the data components of my struct to a file?
struct { unsigned int widthValidated; unsigned int heightValidated; } status; This structure requires 8 bytes of memory space but in actual, we are going to store either 0 or 1 in each of the variables. The C programming language offers a better way to utilize the memory space in such situations.
Structure Padding Processor doesn't read 1byte at a time from memory.It reads 1 word at a time. In 32 bit processor, it can access 4 bytes at a time which means word size is 4 bytes. Similarly in a 64 bit processor, it can access 8 bytes at a time which means word size is 8 bytes.
Above is the alignment of the structure A, and that's why the size of the struct is 32 Bytes. Also, the object a of type struct A is 32 Bytes.
For writing in file, it is easy to write string or int to file using fprintf and putc, but you might have faced difficulty when writing contents of struct. fwrite and fread make task easier when you want to write and read blocks of data.
Microprocessors are not designed to fetch data from arbitrary addresses. Objects such as 4-byte int
s should only be stored at addresses divisible by four. This requirement is called alignment.
C gives the compiler freedom to insert padding bytes between struct members to align them. The amount of padding is just one variable between different platforms, another major variable being endianness. This is why you should not simply "dump" structures to disk if you want the program to run on more than one machine.
The best practice is to write each member explicitly, and to use htonl
to fix endianness to big-endian before binary output. When reading back, use memcpy
to move raw bytes, do not use
char *buffer_ptr;
...
++ buffer_ptr;
struct.member = * (int *) buffer_ptr; /* potential alignment error */
but instead do
memcpy( buffer_ptr, (char *) & struct.member, sizeof struct.member );
struct.member = ntohl( struct.member ); /* if member is 4 bytes */
That is because of structure padding, see http://en.wikipedia.org/wiki/Sizeof#Implementation
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With