Confusion about struct size...

Started by
9 comments, last by Emmanuel Deloget 18 years, 10 months ago
I have the following structure: struct tle_file_header { char header[3]; short version; short tile_count; char width; char height; int offset; int file_size; }; As I understand it, the size of it in bytes should be 17, but sizeof(tle_file_header) is equal to 20. Is it because memory is somehow 4 byte aligned?
Advertisement
Quote:Original post by Giedrius
I have the following structure:

As I understand it, the size of it in bytes should be 17, but sizeof(tle_file_header) is equal to 20. Is it because memory is somehow 4 byte aligned?


Yes - and some fields are padded with invisible values. For example, you probably have this real memory structure
struct tle_file_header_real{  char header[3];  char __unused__0;  short version;  short tile_count;  char width;  char height;  short __unused__1;  int offset;  int file_size;};


Of course, your real structure can be diferent (only the compiler knows it; you can get hints if you try to compute the offset between the beginning of thte structure and a particular member).

It also means that if you change alignement, you also change the size of your structures, of course. But OTOH your code will try to access to non-aligned memory, and such kind of access are very slow.

Another solution is to pack the members. VC++ defines the #pragma pack - have a look to the MSDN for further information.

HTH
You already gave the answer to your question.
Your compiler lays out the struct in memory so that it will be aligned best for your processor (so probably 4 bytes).

So, possibly, your header will have a char prepended to it, and between height and offset 2 bytes are inserted.

You can turn this behaviour off, if you want, using the
#pragma pack(1)
directives.

(EDIT: Oops, Emmanuel Deloget beat me to it!)
You can also reorder the declarations of the variables

struct tle_file_header{int offset;int file_size;short version;short tile_count;char header[3];char width;char height;};


If I remember correctly, a configuration like this will reduce the ammount of padding needed.

"I can't believe I'm defending logic to a turing machine." - Kent Woolworth [Other Space]

Strictly speaking, you shouldn't have to worry about the size of an individual struct while its in memory, only when its heading down to disk. When you have to store several million copies, then you can start worrying. However, this looks like just a singular file record for reading a file. Read via byte, rather than via struct (i.e. read the 7 fields individually).
william bubel
You may also want to think about endianness.

Generally speaking, you never want to raw-write a struct or even a non-byte-size peice of data to disk (or network). Same goes for reading.
Quote:Original post by Rattrap
You can also reorder the declarations of the variables

*** Source Snippet Removed ***

If I remember correctly, a configuration like this will reduce the ammount of padding needed.
Yes it quite likely will, if the compiler is not a compiler that automatically reorders the vars. (I don't know if any do).
The general rule is that things should be listed from the the one that has the largest power of two as a factor, then the next largest etc.

If this is for reading from a file then I'd guess that you have to code to write it also, because most people out there would know how to align the fields better. In which case you're okay to dump the binary straight into the file.
"In order to understand recursion, you must first understand recursion."
My website dedicated to sorting algorithms
Quote:Original post by Rattrap
You can also reorder the declarations of the variables

*** Source Snippet Removed ***

If I remember correctly, a configuration like this will reduce the ammount of padding needed.


In my case, that wouldn't help. The size is still the same, but probably would help in some rare cases.

I have been playing with pragma values and I don't understand why

#pragma pack(4)

struct rgb { char r,g,b; }

sizeof(rgb)=3?

Why not 4, if the packing is set to 4?

Edit: Probably got it, the compiler pads it if there's other variable of different type in the same structure. Is it right?

[Edited by - Giedrius on June 22, 2005 2:15:20 AM]
From MSDN:
"The pragma takes effect at the first structure or union declaration after the pragma is seen; the pragma has no effect on definitions."
"In order to understand recursion, you must first understand recursion."
My website dedicated to sorting algorithms
Quote:Original post by iMalc
From MSDN:
"The pragma takes effect at the first structure or union declaration after the pragma is seen; the pragma has no effect on definitions."


Let's say:

rgb asdf;

There's no difference in sizeof(rgb) and sizeof(asdf).

This topic is closed to new replies.

Advertisement