ProgrammierungEmbedded/Low-level C Entwickler

Erklären Sie, wie Vereinigungen (union) in C funktionieren. Welche Aufgaben werden damit gelöst, wie verwendet man sie richtig und welche typischen Fallstricke treten bei ihrer Verwendung auf?

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

Antwort

Union (Vereinigung) ist ein spezieller Datentyp, der verschiedene Werte im selben Speicherbereich speichert. Bei einer Union liegen alle Mitglieder im Speicher an derselben Adresse, und die Speichermenge entspricht der Größe des größten Mitglieds.

Verwendung:

  • Praktisch zur Einsparung von Speicherplatz, wenn eine Variable zu einem bestimmten Zeitpunkt einen von mehreren Werttypen annimmt;
  • Ermöglicht die Interpretation derselben Bits auf unterschiedliche Weise (z. B. für Low-Level-Zugriff oder Protokolle).

Beispiel:

union Data { int i; float f; char s[4]; }; union Data d; d.i = 0x41424344; // Im Speicher sind jetzt 4 Bytes, die als int, float oder Zeichenfolge gelesen werden können printf("%c%c%c\n", d.s[0], d.s[1], d.s[2]); // herstellerspezifische Ausgabe

Fallstricke und Regeln zur Verwendung:

  • Halten Sie in der Union immer nur ein "gültiges" Feld.
  • Es gibt keine automatisierte Nachverfolgung, welches Feld zuletzt "aktiv" war.
  • Das Lesen eines nicht aktiven Feldes ist undefined behavior.
  • Die Byte-Reihenfolge auf der Plattform ist sehr wichtig (endian!)

Fangfrage

Frage: Was ist der Sinn der Verwendung von Union, wenn man einfach eine Struktur mit mehreren Feldern verwenden kann?

Antwort: Die Verwendung von Union spart Speicherplatz, da zu jedem Zeitpunkt innerhalb nur EIN Wert und nicht alle gleichzeitig gespeichert wird. Bei einer Struktur wird für jedes Feld Speicher reserviert, während in einer Union nur für das größte Feld Speicher reserviert wird, die anderen "teilen" diesen Speicher. Außerdem ermöglicht die Union eine sichere oder absichtliche Umwandlung zwischen verschiedenen Datenrepräsentationen im selben Speicherbereich.

Beispiel:

struct S { int i; float f; } s; // sizeof = sizeof(int) + sizeof(float) union U { int i; float f; } u; // sizeof = max(sizeof(int),sizeof(float))

Beispiele für reale Fehler


Geschichte

In einem Treiberprojekt wurde die Kommunikation mit der Hardware über eine Union mit bitweisen Zugriff auf Daten durchgeführt. Nach einer kleinen Refaktorierung begann der Entwickler, in das falsche Feld der Union zu schreiben, was zu ungültigen Daten und zu einem katastrophalen Systemausfall führte, da in der Union zu jedem Zeitpunkt nur ein Feld "gültig" ist.


Geschichte

Beim Austausch von Netzwerkpaketen über eine Union zur Speicherverwaltung vergaß der Entwickler, die Ausrichtung von Strukturen zu berücksichtigen. Dadurch kam es zu einer Verschiebung um ein Byte, und die Struktur wurde mit falschen Verschiebungen analysiert, was das Protokoll inkompatibel mit dem Original machte.


Geschichte

Bei der Arbeit an einer Serialisierungsbibliothek übergab der Programmierer eine Union per Wert an eine Funktion, ohne das erforderliche Feld vor dem Lesen zu initialisieren. Infolgedessen wurden die Daten fehlerhaft serialisiert, es gab Müll im Ausgangsstream, und die ursprünglichen Informationen konnten nicht wiederhergestellt werden.