struct Größe



  • Hallo,

    ich hab zwei structs:

    typedef struct s1
    {
        unsigned char  kennung;
        unsigned char  typ;
        unsigned short nummer;
        unsigned char  attribut;
        unsigned char  sprache;
        signed long    laenge;
        signed long    sektor;
        unsigned short reserviert;
    }S1;
    
    typedef struct s2
    {
        unsigned char  reserviert;
        unsigned char  reserviert2;
        unsigned short dir_nr;
        unsigned long  part_nr;
        unsigned short reserviert3;
        signed long    sektor;
        unsigned short reserviert4;
    }S2;
    

    Beide structs sind rein von den Datentypen 16byte groß.
    VS2012 macht mir daraus aber 20byte. Warum ?

    Ich hab zwar schon paar Sachen gegoogelt und gelesen und weiß dass das irgendwie mit der Speicherverwaltung zusammenhängt aber versteh in meinem Fall nicht warum.

    Kann mir da jmd helfen ?

    Viele Grüße



  • Ein Compiler versucht an dieser Stelle selbständig zu optimieren, d.h. bestimme struct-Elemente an bestimmten Adressen auszurichten (Alignment) und fügt dazu sogenannte Padding-Bytes zwischen den Elementen einer struct ein.
    Dadurch ist die Gesamtgröße der Struktur u.U. größer als die Summe der Einzelgrößen.
    Verschiedene Compiler bieten unterschiedliche Wege an, dieses Padding auszuschalten.



  • Hallo,

    danke für die Antwort.
    Ja, das hab ich auch schon gelesen, hab auch schon geschafft es abzuschalten.

    Worum es mir ging, in meinem C-Buch ist ein Beispiel eines struct in dem die Datentypen zusammen 5byte haben (char + int). Und es steht dabei der Compiler wird aus dem struct vermutlich 8 oder 16byte machen, für schnelleren Zugriff.

    Das ist mir völlig klar, da macht das auch Sinn.

    Aber meins hat doch schon 16byte, hab ich extra so gebaut. Und 20byte ist für mich irgendwie viel krummer als meine 16byte. Deswegen versteh ich in diesem Fall nicht warum er padded und vorallem nicht wo (wobei das könnte ich mal schauen, das lässt sich über die Adressen ja rauskriegen).

    Viele Grüße



  • Versuch's mal so:

    typedef struct s1
    {
        unsigned char  kennung;
        unsigned char  typ;
        unsigned char  attribut;
        unsigned char  sprache;
        signed long    laenge;
        signed long    sektor;
        unsigned short nummer;
        unsigned short reserviert;
    }S1;
    
    typedef struct s2
    {
        unsigned char  reserviert;
        unsigned char  reserviert2;
        unsigned short dir_nr;
        unsigned long  part_nr;
        signed long    sektor;
        unsigned short reserviert3;
        unsigned short reserviert4;
    }S2;
    

    http://ideone.com/DKPkIe

    Paßt das besser?
    Das Padding würde ich nach möglichkeit nicht abschalten. Schadet im Zweifel der Performanz.



  • Du hast meine Antwort nicht verstanden. Es geht nicht um ein Alignment der Gesamtgröße, sondern um ein Alignment der einzelnen Elemente.
    Das kann man sich schön mit offsetof() (von den meisten Fachbüchern ignoriert) anschauen. offsetof gibt die Distanz in Bytes vom Anfang einer struct bis zum Einzel-Element zurück.

    int main(void) {
       struct s {
    	char c;
    	double d;
       } x;
       struct a {
    	double d;
    	char c;
       } y;
    	printf("%lu %lu\n",(unsigned long)sizeof x,(unsigned long)sizeof y);
    	printf("%lu %lu",(unsigned long)offsetof(struct s,d),(unsigned long)offsetof(struct a,c));
    	return 0;
    }
    

    http://ideone.com/VtUghz
    Bei "struct s" wird also das 2. Element "double d" ausgerichtet, indem nach dem 1. Element 3 Paddingbytes eingefügt werden, damit auf "double d" möglichst optimiert zugegriffen werden kann.



  • Caligulaminus schrieb:

    Versuch's mal so:

    Die Strukturen sehen mir so aus, als sollten sie ein bestimmtes vorgegebenes Layout nachbilden. Umordnen kommt deshalb wohl nicht in Frage.
    Alternativ könnte man zum Lesen und Schreiben der Strukturen eigene Funktionen bereitstellen, die feldweise arbeiten. Aber wenn gepacktes Layout möglich ist, würde ich mir den Aufwand und die zusätzlichen Fehlerquellen ersparen.


Log in to reply