views:

58

answers:

3

I'm trying to write a simple TGA image file saver as a learning exercise in C++. I'm basing my code on an example TGA loader that declares a struct for the header and then uses fread() to load the entire header in one go.

My program isn't working right now, and it seems like there are two extra bytes being written to the file. I printed the sizeof my struct and it's two bytes too large (20 instead of the correct 18). After a little reading I think the problem is related to data alignment and padding (I'm not very familiar with how structs get stored).

My question is what's a good solution for this? I guess I could write the struct's components byte-by-byte, instead of using fwrite() to write the entire struct at once, which is what I'm going now. I assumed that if it worked when loading the header, it would also work when writing it. Was my assumption incorrect?

+4  A: 

Compilers are allowed to, and frequently do, insert padding bytes into structures so that fields are aligned on appropriate memory addresses.

The simplest solution is to instruct the compiler to "pack" the structure, which means to not insert any padding bytes. However this will make data access to the structure slower, and the means of doing it are compiler-dependent. If you want to be portable and efficient, the only way to go is writing the fields individually.

Tyler McHenry
+1  A: 

It did not work even when loading it. You have a couple of options:

  1. Use compiler specific directives (#pragma packed, etc.) to force your structure to be 18 bytes.

  2. Write the code more portable by using offsets and pointers to get/set the buffer fields.

Amardeep
A: 

Elements of a struct are generally arranged on 4byte boundaries.

if you have shorts, or chars in your struct, the struct is larger than the sum of the individual element sizes.

Martin Beckett