Author Topic: C++ Struct Size Bug??  (Read 4174 times)

Alhexx

  • *
  • Posts: 1894
    • View Profile
    • http://www.alhexx.com
C++ Struct Size Bug??
« on: 2002-08-26 18:34:58 »
Well, I'm currently trying to write an editor for Dino Crisis 2 Memory Card Savegames. However, I have one problem, and I have no idea how to solve it.

Here's the important code:

Code: [Select]

typedef unsigned char byte;
typedef unsigned short word;
typedef unsigned int dword;

typedef struct
{ // SIZE: 10 Bytes
word Unknown1;
byte PrimWeapon;
byte SecnWeapon;
dword Unknown2;
word Unknown3;
} t_dc2_player;


Okay, everything's fine 'till now. As you can see (and you can count yourself) t_dc2_player is exactly 10 Bytes big. However, if I use it in another struct, let's take this for example:
Code: [Select]

typedef struct
{
int someInt;
t_dc2_player Dylan;
t_dc2_player Regina;
int anotherInt;
} someStruct;


Now I have this problem: someInt and Dylan are read out right, but ... the others aren't. The reason seems to be than t_dc2_player is not 10 but 12 bytes big in c++ (at least that's what the sizeof() fucntio says)
So, for Dylan 12 Bytes are read out from a file (or another buffer), but only 10 bytes are stored in the struct. The 2 bytes directly after Dylan (or let's say: the first 2 bytes of Regina) simply disappear!! They're not here!!


Has anybody got an idea how to solve this???

 - Alhexx

ficedula

  • *
  • Posts: 2178
    • View Profile
    • http://www.ficedula.co.uk
C++ Struct Size Bug??
« Reply #1 on: 2002-08-26 22:27:37 »
Aha ... you've hit on something called 'Data alignment'.

Basically, on modern computers, data is faster to access in certain positions. A normal CPU works in 32-bit mode (4 bytes) so data on 4-byte boundaries is quicker to access...

Example:  Addresses  0, 4, 8, 12 ....   are quicker to access than 1, 3, 5, ....

In fact, sometimes 8 byte boundaries are even quicker than 4 byte boundaries.

In order to make use of this fact compilers often 'pad out' data so each variable rests on a 4-byte boundary (or some other boundary...odd numbered addresses are the worst of all). This often leads to records size's being multiples of 4 or 8 ... if they should be less than that, then the compiler just adds 'padding' (wasted space) to MAKE them that big. Result: faster code. Problem: You've just discovered it!

In Delphi, you can mark a record as 'packed' to force it NOT to use padding. That's exactly what you do for file structures ;)   C++ does let you do that somehow, but I remember being told the method in question varies from compiler to compiler. So start hunting through your docs :)

phaeron

  • *
  • Posts: 30
    • View Profile
C++ Struct Size Bug??
« Reply #2 on: 2002-08-27 03:30:18 »
For Visual C++, you can disable padding as follows:
Code: [Select]

#pragma pack(push)
#pragma pack(1)
struct Foo {
   ...
};
#pragma pack(pop)

A better idea, though, is just to split the dword member into two words and be done with it.  Your struct will generally be free of padding if each element is aligned to its size and the struct size is evenly divisible by the largest element.

The rule for sizeof() is that it returns the size of an object as if it were an array element.  Even though your struct doesn't need to be padded when used by itself, sizeof() still returns the padded size.

mirex

  • *
  • Posts: 1645
    • View Profile
    • http://mirex.mypage.sk
C++ Struct Size Bug??
« Reply #3 on: 2002-08-27 11:59:21 »
Yes i had the same problem when i started with Visual Cpp. You can set the structure alignment in Project/Settings/C,C++/ Category: Code Generation / Struct member alignment.
You can set it to 1byte and it will work.

But im not switching this, im just reading data in parts.
Code: [Select]
fread( &someStruct.someInt, 1, sizeof( int ), file );
fread( &someStruct.Dylan, 1, 10, file );
fread( &someStruct.Regina, 1, 10, file );
fread( &someStruct.anotherInt, 1, sizeof( int ), file );


I dunno why, i forgot, but i think there was some problem with something when i switched that member alignment ... but maybe there wasnt .. you try it :)

--edit--
now i remember. when switching this alignment, it could produce some bugs if you are using some 3rd party libs in your project.

Qhimm

  • Founder
  • *
  • Posts: 1996
    • View Profile
    • Qhimm.com
C++ Struct Size Bug??
« Reply #4 on: 2002-08-27 12:33:39 »
That problem you mentioned was probably complaints that the precompiled headers didn't match the new settings. The bad part is that the new settings (alignment) will be ignored. Do a clean build to fix this.

Alhexx

  • *
  • Posts: 1894
    • View Profile
    • http://www.alhexx.com
C++ Struct Size Bug??
« Reply #5 on: 2002-08-27 12:58:25 »
All:
I've never heard 'bout such a problem before ... so:


phaeron: Splitting up the dword, yes, that's exactly what I've done. Now it worx :wink:

 - Alhexx