Betrachten wir zunächst folgenden Beispielcode:

#include <stdalign.h>
#include <stdio.h>

struct my_first_type {
    short int x;
    unsigned int y;
};

struct my_second_type {
    unsigned int y;
    short int x;
};

int main()
{
    struct my_first_type one;
    struct my_second_type two;

    printf("addresses: struct=%p - x=%p, y=%p\n", &one, &one.x, &one.y);
    printf("sizeof(struct my_first_type) : %zd\n", sizeof(struct my_first_type));
    printf("alignof(struct my_first_type): %zd\n", alignof(struct my_first_type));

    printf("addresses: struct=%p - x=%p, y=%p\n", &two, &two.x, &two.y);
    printf("sizeof(struct my_second_type) : %zd\n", sizeof(struct my_second_type));
    printf("alignof(struct my_second_type): %zd\n", alignof(struct my_second_type));

    return 0;
}

Stukturen müssen, genau wie jeder andere Datentyp auch, die Regeln der Speicherausrichtung beachten. Daraus folgt, dass die einzelnen Felder der Struktur korrekt ausgerichtet sein müssen. Werden verschieden große Felder verwendet, kann es notwendig werden, Lücken zwischen einzelnen Feldern zu lassen. Da sich Lücken aber nicht programmieren lassen, werden sie stattdessen durch Füll-Bytes, die sogenannten "Padding Bytes", repräsentiert.

Das Alignment einer Struktur ergibt sich aus dem Alignment des größten Feldes. Das größte Feld in "my_second_type" ist z.B. vom Typ int und damit 4 Byte groß. Die gesamte Struktur hat damit ein Alignment von 4. Weiterhin wird die Größe von Strukturen auf ein ganzzahliges Vielfaches des Alignments aufgefüllt. "my_second_type" wird somit 8 und nicht 6 Byte groß. Die entstehende Lücke am Ende der Struktur füllt der Compiler automatisch mit Padding-Bytes. 

"my_first_type" sieht im Speicher, aufgrund der geänderten Reihenfolge der Felder, anders aus. Auch diese Struktur hat ein Alignment von 4, x liegt aber nicht auf einer durch 4 teilbaren Speicheraddresse, sollte es direkt auf y folgen. Der Compiler fügt die Padding-Bytes daher hinter y ein, um x korrekt auszurichten. Das Bild am Anfang dieses Themas verdeutlicht den Zusammenhang.


Explizites Padding

Padding-Bytes existieren, auch wenn wir sie nicht im Code sehen oder direkt ansprechen können. Aus diesem Grund werden Padding-Bytes in der Programmierung oft explizit angelegt. Ein Leser des Codes ist so in der Lage, die Padding-Bytes in der Struktur zu sehen. Die entsprechenden Felder werden oft als "reserved" bezeichnet.

#include <stdalign.h>
#include <stdio.h>

struct my_first_type {
    short int x;
    short int reserved;
    unsigned int y;
};

struct my_second_type {
    unsigned int y;
    short int x;
    short int reserved;
};

int main()
{
    struct my_first_type one;
    struct my_second_type two;

    printf("addresses: struct=%p - x=%p, y=%p\n", &one, &one.x, &one.y);
    printf("sizeof(struct my_first_type) : %zd\n", sizeof(struct my_first_type));
    printf("alignof(struct my_first_type): %zd\n", alignof(struct my_first_type));

    printf("addresses: struct=%p - x=%p, y=%p\n", &two, &two.x, &two.y);
    printf("sizeof(struct my_second_type) : %zd\n", sizeof(struct my_second_type));
    printf("alignof(struct my_second_type): %zd\n", alignof(struct my_second_type));

    return 0;
}
Zuletzt geändert: Freitag, 18. Mai 2018, 17:21