sizeof struct ergibt anderen Wert
-
Hallo,
ich hoffe ihr könnt mich über folgenden fall aufklären.
ich hab einen 16Bit Compiler. Das sizeof der folgenden Struktur ergibt 14, warum? es sind doch nur 13 Bytes.
typedef struct { BYTE Status; UINT16 PowerCHA; UINT16 VswrCHA; UINT16 PowerCHB; UINT16 VswrCHB; UINT16 TempPower; UINT16 TempAmbient; } SStatus;
zudem kommt noch:
SStatus TestState; memcpy(&TestState,&xbuf[5],13);
xbuf ist unsigned char. Bei TestState.TempAmbient kommt eine anderer Wert raus als wenn ich folgendes mache:
memcpy(&TestState,&xbuf[6],12);
sitzt nun schon seit stunden dran und versteh es einfach nicht...
-
...
-
Compiler dürfen und werden Füllbytes in Strukturen einbauen, wenn dies technische Vorteile bringt. Hier wird wohl zwischen
Status
undPowerCHA
ein zusätzliches Byte eingebaut werden.Möglichkeit A: Viele Compiler haben Schalter, die sie dazu zwingen, diese Füllbytes wegzulassen. Aber: Das hat, wie gesagt, technische Nachteile. Das solltest du wirklich nur tun, wenn es unbedingt nötig ist.
Besser:
Möglichkeit B: Programmier eben so, dass dies keine Rolle spielt. Das sollte kein Problem sein, genau dazu ist C doch erfunden worden. Selbst wenn du mal ganz maschinennah rumfrickeln musst, gibt es immer noch sizeof, offsetof, Adressoperator, usw. , die korrekt mit den Füllbytes arbeiten.
Und im besten Fall solltest du dich gar nicht auf diese Ebene begeben brauchen.
-
typedef unsigned char BYTE; typedef unsigned short UINT16; typedef struct { BYTE Status; UINT16 PowerCHA; UINT16 VswrCHA; UINT16 PowerCHB; UINT16 VswrCHB; UINT16 TempPower; UINT16 TempAmbient; } SStatus; int main() { SStatus s={0}; unsigned char x[]={0,0,0,0,0,0,0xaa,0xbb,0xcc,0xdd,0xee,0xff,0x11,0x22,0x33,0x44,0x55,0x66},*z=&s; memcpy( z+offsetof(SStatus,PowerCHA),x+6,12 ); /* alternativ zu offsetof kannst du auch mit & arbeiten (&s.PowerCHA) */ s.Status = 123; /* Status musst du separat setzen */ return 0; }
Das Bytefolge-Problem sollte dir aber bewusst sein, wenn du UINT16 mit unsigned char via memcpy befüllst, ggü. der direkten Befüllung per Zuweisung.
memcpy( &s.PowerCHA,"\x11\x22",2 ); ggü. s.PowerCHA = 0x1122;
kann also durchaus unterschiedlich ablaufen.