PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : [C++]Speicherplatz einer Struktur


pippo
2006-04-25, 17:52:42
Hab grad ein kleines Verständnisproblem mit folgendem Code:

typedef struct {
enum {Mo, Di, Mi, Do, Fr, Sa, So} WoTag;
unsigned short Minute, Stunde;
unsigned short Tag, Monat, Jahr;
char *Datum;
}tDatum;

Lass ich nun die Größe von tDatum mit Hilfe von sizeof(tDatum) ausgeben, bekomm ich als Ergebnis 20, doch wo kommen die her?
Kommentier ich von tDatum alles aus, bekomm ich für sizeof(tDatum) die 1 Byte, was mir auch einleuchtet. Alle unsigned short belgen 2 Byte, enum 4 Byte (wieso eigentlich ?) und char *Datum ebenfalls 4 Byte (was ich ebenfalls nicht versteh).

Wie kommen nun die 20 Byte zustande?

Gast
2006-04-25, 17:59:04
Lass ich nun die Größe von tDatum mit Hilfe von sizeof(tDatum) ausgeben, bekomm ich als Ergebnis 20, doch wo kommen die her?
Kommentier ich von tDatum alles aus, bekomm ich für sizeof(tDatum) die 1 Byte, was mir auch einleuchtet. Alle unsigned short belgen 2 Byte, enum 4 Byte (wieso eigentlich ?) und char *Datum ebenfalls 4 Byte (was ich ebenfalls nicht versteh).

Wie kommen nun die 20 Byte zustande?

enum ist 4 Byte groß, weils im Grunde nichts weiter als ein 32-Bit Integer ist.
char* Datum ist 4 Byte groß, weils ein Zeiger auf eine 32 bittige Adresse ist.

zeckensack
2006-04-25, 18:15:14
Hab grad ein kleines Verständnisproblem mit folgendem Code:

typedef struct {
enum {Mo, Di, Mi, Do, Fr, Sa, So} WoTag;
unsigned short Minute, Stunde;
unsigned short Tag, Monat, Jahr;
char *Datum;
}tDatum;

Lass ich nun die Größe von tDatum mit Hilfe von sizeof(tDatum) ausgeben, bekomm ich als Ergebnis 20, doch wo kommen die her?
Kommentier ich von tDatum alles aus, bekomm ich für sizeof(tDatum) die 1 Byte, was mir auch einleuchtet. Alle unsigned short belgen 2 Byte, enum 4 Byte (wieso eigentlich ?) und char *Datum ebenfalls 4 Byte (was ich ebenfalls nicht versteh).

Wie kommen nun die 20 Byte zustande?Padding, Alignment ...
Versuch's mal so:typedef struct {
char *Datum;
unsigned short Minute, Stunde;
unsigned short Tag, Monat, Jahr;
enum {Mo, Di, Mi, Do, Fr, Sa, So} WoTag;
}tDatum;Die Elemente sind hier absteigend nach der Größe ihrer Datentypen sortiert.
(die meisten Compiler benutzen für enums nur so viel Platz wie notwendig ist, in diesem Fall 1 Byte, weil die enum weniger als 256 Zustände hat)

Ich bin mir ziemlich sicher dass sizeof(tDatum) nun einen anderen Wert liefern wird. Ich tippe auf 15 oder 16 Byte.

Lies mal in deiner Compiler-Dokumentation nach, ob es Optionen gibt die structs beeinflussen. Relevante Suchbegriffe wären "struct packing" und "struct padding".

pippo
2006-04-25, 18:29:34
Ich werd mal danach suchen, ja. Verwende übrigends Visual Studio .net 2003 prof.

Das Ändern der Reihenfolge hat übrigends nichts an der Größe geändert

Gast
2006-04-25, 19:52:03
Lass es so das ist schneller und macht heute nichts mehr aus. In ausnahmefällen kann man da mit Compileroptionen dran rumpfuschen.
Für embedden programming sollte es eine size-optimierung geben (so ist das zumindest bei avr)

wie gesagt sind die Stichworte: Padding, Alignment

zeckensack
2006-04-26, 19:02:37
Ich werd mal danach suchen, ja. Verwende übrigends Visual Studio .net 2003 prof.

Das Ändern der Reihenfolge hat übrigends nichts an der Größe geändertDann nutzt der Compiler 4 Byte für die enum, obwohl das nicht notwendig ist.
Nochmals zum Verständnis, der Compiler fügt "Löcher" in die struct ein, damit für jedes Element das natürliches Alignment eingehalten wird. Natürliches Alignment bedeutet dass die Adresse eines Werts der (bedingt durch den Typ) vier Byte belegt auch glatt durch vier teilbar ist.
In deinem Fall werden wohl nach den fünf ushorts (10 Byte) zwei "nutzlose" Füllbytes eingefügt, damit die Adresse des nächsten Elements wieder durch vier teilbar ist.
(10/4=2,5 vs 12/4=3)

pippo
2006-04-28, 10:36:37
Hätte enum jetzt nur 1 Byte belegt, hätte dann der Compieler auch 3 nutzlose Füllbytes eingefügt?

Neomi
2006-04-28, 11:35:44
Hätte enum jetzt nur 1 Byte belegt, hätte dann der Compieler auch 3 nutzlose Füllbytes eingefügt?

Nein, da ein 2 Byte großer Wert folgt. Der wird auf die nächste 2 Byte Grenze gesetzt, also 1 Füllbyte. Durch die Verschiebung wären dann noch die 2 Füllbytes weiter hinten unnötig. Die Struktur wäre also 16 Bytes (32 Bit Pointer) oder 20 Bytes (64 Bit Pointer) groß.