Frage zur Größe eines struct



  • Hi,

    ich habe folgendes Beispiel:

    #include <stdio.h>
    
    struct myStruct {
       char a;  // 1 byte
       int b;  // 4 byte
       double c;  // 8 byte
    };
    
    union myUnion {
       char a;
       int b;
       double c;
    };
    
    int main(void)
    {
       printf("Size of myStruct: %d byte\n", sizeof(struct myStruct));
       printf("Size of myUnion: %d byte\n", sizeof(union myUnion));
    
       return 0;
    }
    

    und erhalte als Ergebnis 16 byte für das struct??? Nach meiner Rechnung sind es 1+4+8 = 13 byte.

    Wo kommen die restlichen 3 byte her?





  • Siehe auch: https://en.cppreference.com/w/c/language/object (ein wichtiger Satz ist hier "In order to satisfy alignment requirements of all members of a struct, padding may be inserted after some of its members.")
    oder auch mal was auf Deutsch: https://learn.microsoft.com/de-de/cpp/c-language/alignment-c?view=msvc-170



  • @ledi
    In deinem Beispiel heisst das konkret dass b an einem durch 4 teilbaren Offset liegen muss, da int üblicherweise ein "alignment requirement" von 4 hat.
    Der Offset direkt hinter a wäre allerdings 1. Um zu einem durch 4 teilbaren Offset zu kommen, müssen 3 sog. "padding bytes" eingefügt werden (1 + 3 = 4).

    c muss dann üblicherweise an einem durch 8 teilbaren Offset liegen (alignment requirement von double). Dort passt es dann so schon wieder, da 4 + 4 = 8, und 8 ist ja bereits durch 8 teilbar.

    Zuletzt muss dann noch sichergestellt werden dass auch die Grösse der Struktur zum alignment requirement der Struktur passt. Das alignment requirement der Struktur ist einfach das grösste alignment requirement eines Struktur-Members, in diesem Fall also auch wieder 8. Die Grösse ohne zusätzliches Padding ist 8 + 8 = 16, und das ist auch direkt durch 8 teilbar. D.h. es bleibt bei 16.

    Anderes Beispiel:

    struct myStruct2 {
       int x;  // 4 byte
       double y;  // 8 byte
       char z;  // 1 byte
    };
    

    x kommt auf Offset 0, dazu gibt es nicht viel zu sagen.

    Der Offset direkt hinter x ist 4. Der Offset von y muss aber durch 8 teilbar sein. Also kommen hier 4 padding bytes dazwischen und y bekommt den Offset 8.

    Der Offset direkt hinter y ist 16. Da z nur ein alignment requirement von 1 hat passt es überall. z bekommt also den Offset 16.

    Der Offset direkt hinter z ist 17. Auf Grund des Members y ist das alignment requirement von myStruct2 allerdings 8. D.h. die Grösse von myStruct2 muss durch 8 teilbar sein, und 17 ist eben nicht durch 8 teilbar. Daher werden hinter z noch 7 weitere padding bytes eingefügt um die Grösse auf einen durch 8 teilbaren Wert zu bringen.

    Daher ist die Grösse von myStruct2 17 + 7 = 24.


Anmelden zum Antworten