ProgrammierungSystemprogrammierer

Erklären Sie die Funktionsweise von verschachtelten Strukturen und der Ausrichtung (struct alignment) in C. Wie kann die Größe einer Struktur kontrolliert werden und welche Probleme können auftreten?

Bestehen Sie Vorstellungsgespräche mit dem Hintsage-KI-Assistenten

Antwort.

In der Programmiersprache C können Strukturen (struct) andere Strukturen und verschiedene Datentypen enthalten. Die Anordnung der Felder innerhalb der Struktur kann jedoch deren Größe und Ausrichtung beeinflussen. Der Compiler fügt zusätzliche Bytes (Padding) hinzu, um die Ausrichtung (Alignment) des größten Feldes zu gewährleisten. Dies ist wichtig für die Leistung und das korrekte Funktionieren des Prozessors.

Wenn eine Struktur verschachtelte Strukturen enthält, wird die Ausrichtung rekursiv angewendet:

  • Die Größe der Struktur ist immer ein Vielfaches der Ausrichtung des größten Feldes.
  • Verschachtelte Strukturen können zu unerwarteten Abständen führen, wodurch sizeof(struct) größer wird als die Summe von sizeof(Feldern).

Wie kann man die Größe kontrollieren?

  1. Felder in absteigender Reihenfolge der Größe sortieren.
  2. Ausrichtungsdirektiven verwenden (z. B. #pragma pack in MSVC oder das Attribut __attribute__((packed)) in GCC/Clang).

Beispiel:

#include <stdio.h> struct Inner { char c; int x; }; struct Outer { char a; struct Inner b; short s; }; int main() { printf("sizeof(struct Inner) = %zu\n", sizeof(struct Inner)); printf("sizeof(struct Outer) = %zu\n", sizeof(struct Outer)); return 0; } // sizeof(struct Inner) = 8 (auf 64-Bit), sizeof(struct Outer) = 16 oder 24

Die Verwendung von pack und packed verringert die Größe, indem die Ausrichtung ignoriert wird, kann jedoch die Leistung beeinträchtigen oder Fehler auf einigen Plattformen (ARM, DSP usw.) verursachen.


Fangfrage.

Frage: Kann man garantieren, dass die Größe der gleichen Struktur auf allen Plattformen gleich ist?

Antwort: Nein! Der C-Standard garantiert nicht die gleiche Ausrichtung, die Byte-Reihenfolge (Endianness) und kann Padding zwischen den Feldern und am Ende der Struktur "hinzufügen". Für die binäre Kompatibilität von Strukturen verwenden Sie manuelle Steuerung der Ausrichtung und testen Sie immer explizit sizeof auf jeder Zielplattform.

Beispiel:

struct Data { char c; int x; }; // sizeof(Data) ist normalerweise 8 auf 64-Bit, 5 oder 8 auf 32-Bit

Geschichte

Beim Austausch einer Struktur zwischen einem Mikrocontroller (ARM) und einem PC über ein binäres Protokoll stimmten die Daten von ARM nicht mit den Erwartungen auf dem PC überein – aufgrund von unterschiedlichem Padding und Byte-Reihenfolge. Dies führte zu falschen dekodierten Parametern, was zu physischen Steuerfehlern des Geräts führte.


Geschichte

Im Netzwerkprotokoll wurden zur Beschleunigung des Datentransfers gepackte Strukturen hinzugefügt, ohne zu berücksichtigen, dass auf Plattformen ohne Ausrichtung einzelne Felder nicht funktionierten (der Prozessor unterstützte keinen Miss-aligned Zugriff). Ergebnis: Hardware-Ausnahmen beim Arbeiten mit Netzwerkpaketen.


Geschichte

Der Server arbeitete mit einer externen Datei, die aus Strukturaufzeichnungen bestand. Nach einem Compiler-Update änderte sich die Größe der Struktur (anderes Alignment). Alte Daten in der Datei konnten nicht mehr korrekt gelesen werden, und ein Teil der Informationen wurde "beschädigt."