Flexible Array-Member in C-Strukturen für dynamische Datenbehandlung meistern
Flexible Array Member ermöglichen die Handhabung von Arrays innerhalb von Strukturen ohne festgelegte Größe. Diese Arrays erhalten ihre Größe zur Laufzeit. Eine Struktur in C ist ein benutzerdefinierter Datentyp, bei dem mehrere Member verschiedener Datentypen unter einem Namen zusammengefasst werden.
Nachfolgend die Syntax für die Deklaration einer Struktur in C:
struct StructName {
daten_typ member1;
daten_typ member2;
// ...
};
Jeder Member kann einen unterschiedlichen Datentyp haben.
Flexible Array Member erweitern Strukturen, indem sie ein dynamisch dimensioniertes Array am Ende der festen Member halten – alles zusammen in einem zusammenhängenden Speicherblock. In diesem Kapitel sehen wir, wie sie innerhalb von Strukturen funktionieren.
Flexible Array Member in Strukturen
Der flexible Array-Member muss am Ende der Struktur deklariert werden, und es muss mindestens ein weiterer Member davor existieren.
Folgende Syntax deklariert ein flexibles Array-Member in einer Struktur:
struct StructName {
daten_typ member1;
daten_typ flexibles_array[]; // flexibles Array-Member
};
Hier ist daten_typ der Datentyp des Arrays und arrayName[] das flexible Array ohne feste Größe.
Speicherallokation für flexible Array-Member
Da ein flexibler Array-Member keine feste Größe hat, allokiert der Compiler keinen Speicher dafür innerhalb der Struktur. Der sizeof-Operator berechnet nur die Größe der festen Member, ohne das flexible Array. Daher müssen wir den Speicher manuell allokieren, wenn wir solche Strukturen erstellen.
Der gesamte benötigte Speicher berechnet sich wie folgt:
Gesamtspeicher = sizeof(Struktur) + (Anzahl Elemente × sizeof(Elementtyp))
Hierbei gibt sizeof(Struktur) den Speicher für die festen Member an, und (Anzahl Elemente × sizeof(Elementtyp)) den Speicher für das flexible Array. Die Summe ergibt den insgesamt zu allokierenden Speicher.
Beispiel 1: Speicherallokation für ein flexibles Array-Member
Im folgenden Beispiel definieren wir eine Struktur mit einem festen Member und einem flexiblen Array und allokieren Speicher für das flexible Array.
#include <stdio.h>
#include <stdlib.h>
struct Example {
int id;
int arr[]; // flexibles Array-Member
};
int main() {
int size = 5;
// Speicher für Struktur + flexibles Array allokieren
struct Example *e = malloc(sizeof(struct Example) + size * sizeof(int));
if (e != NULL) {
printf("Gesamt allokierter Speicher: %zu Bytes\n", sizeof(struct Example) + size * sizeof(int));
free(e);
}
return 0;
}
Hier liefert sizeof(struct Example) 4 Bytes für den Member id. Der Speicher für das flexible Array beträgt 5 × sizeof(int) = 20 Bytes. Gesamt allokierter Speicher: 4 + 20 = 24 Bytes. Die Ausgabe:
Gesamt allokierter Speicher: 24 Bytes
Beispiel 2: Zugriff auf ein flexibles Array in einer Struktur
In diesem Beispiel definieren wir eine Student-Struktur mit einem festen Member (id) und einem flexiblen Array-Member (marks). Wir allokieren dynamisch Speicher für das flexible Array und greifen auf seine Elemente zu. Zugriff über die allokierte Größe hinaus führt zu undefiniertem Verhalten, daher greifen wir nur auf marks[0] bis marks[2] zu.
#include <stdio.h>
#include <stdlib.h>
struct Student {
int id;
int marks[]; // flexibles Array-Member
};
int main() {
int subjects = 3;
// Speicher für Struktur + flexibles Array allokieren
struct Student *s = malloc(sizeof(struct Student) + subjects * sizeof(int));
if (s != NULL) {
s->id = 102;
s->marks[0] = 80;
s->marks[1] = 75;
s->marks[2] = 88;
printf("Studenten-ID: %d\n", s->id);
printf("Noten: %d, %d, %d\n", s->marks[0], s->marks[1], s->marks[2]);
printf("Gesamt allokierter Speicher: %zu Bytes\n", sizeof(struct Student) + subjects * sizeof(int));
free(s);
}
return 0;
}
Die Ausgabe des Programms:
Studenten-ID: 102 Noten: 80, 75, 88 Gesamt allokierter Speicher: 16 Bytes
Dynamische Größenänderung flexibler Array-Member
Flexible Arrays können mit der realloc()-Funktion vergrößert oder verkleinert werden. Diese Funktion erweitert entweder den bestehenden Speicherblock oder allokiert einen neuen Block und kopiert die vorhandenen Daten automatisch.
Um ein flexibles Array zu vergrößern, rufen wir realloc() mit der neuen Gesamtgröße auf, berechnet nach der Formel:
sizeof(Struktur) + (neue_Anzahl_Elemente × sizeof(Elementtyp))
Hinweis: Speichern Sie das Ergebnis von realloc() immer in einem temporären Zeiger. Schlägt die Allokation fehl, bleibt der ursprüngliche Zeiger erhalten. Aktualisieren Sie nach der Größenänderung den Größen-Zähler und initialisieren Sie nur die neu hinzugefügten Elemente.
Beispiel 3: Dynamische Größenänderung flexibler Array-Member
In diesem Beispiel erstellen wir eine Student-Struktur, die zunächst 3 Noten hält. Später vergrößern wir das flexible Array auf 6 Noten mittels realloc(). Die bereits gespeicherten Noten bleiben unverändert, manuelles Kopieren entfällt.
#include <stdio.h>
#include <stdlib.h>
struct Student {
int id;
int count; // Dieses Feld hilft, die aktuelle Array-Größe zu verfolgen
int marks[]; // Flexibles Array-Member
};
int main() {
// Schritt 1: Initialallokation für 3 Noten
int initial_elements = 3;
struct Student *s = malloc(sizeof(struct Student) + initial_elements * sizeof(int));
if (s != NULL) {
s->id = 101;
s->count = initial_elements; // Aktuelle Array-Größe speichern
// Initiale Größen anzeigen
printf("Strukturgröße: %zu Bytes\n", sizeof(struct Student)); // Ausgabe: 8 Bytes (id + count)
printf("Initiale Array-Elemente: %d\n", s->count); // Ausgabe: 3
printf("Initialer Gesamtspeicher: %zu Bytes\n", sizeof(struct Student) + initial_elements * sizeof(int)); // Ausgabe: 20 Bytes
// Schritt 2: Vergrößerung auf 6 Noten
int new_elements = 6;
struct Student *temp = realloc(s, sizeof(struct Student) + new_elements * sizeof(int));
if (temp != NULL) {
s = temp;
s->count = new_elements; // Array-Größen-Tracker aktualisieren
// Neue Größen anzeigen
printf("\nNach Vergrößerung:\n");
printf("Strukturgröße: %zu Bytes\n", sizeof(struct Student)); // Immer noch 8 Bytes
printf("Neue Array-Elemente: %d\n", s->count); // Ausgabe: 6
printf("Neuer Gesamtspeicher: %zu Bytes\n", sizeof(struct Student) + new_elements * sizeof(int)); // Ausgabe: 32 Bytes
}
free(s);
}
return 0;
}
Die folgende Ausgabe zeigt die Strukturgröße und den Gesamtspeicher für das initiale und das vergrößerte flexible Array.
Strukturgröße: 8 Bytes Initiale Array-Elemente: 3 Initialer Gesamtspeicher: 20 Bytes Nach Vergrößerung: Strukturgröße: 8 Bytes Neue Array-Elemente: 6 Neuer Gesamtspeicher: 32 Bytes
In diesem Kapitel haben wir flexible Array-Member in C-Strukturen kennengelernt. Sie werden am Ende einer Struktur deklariert, verarbeiten variabel lange Daten, sparen Speicher und passen sich leicht an unterschiedliche Datengrößen an. Wir haben auch gesehen, wie man sie allokiert, darauf zugreift und ihre Größe ändert.
C Sprache
- Die C for-Schleife meistern: Syntax, Mechanik und praktische Beispiele
- std::map in C++ meistern: Umfassender Guide mit Code‑Beispielen
- C# Interfaces verstehen: Definition, Beispiel und praktische Anwendung
- C++ Klassen & Objekte: Praktischer Leitfaden zur objektorientierten Programmierung
- C Variablen, Datentypen und Konstanten – Ein praktischer Leitfaden
- Top 15 C++ Online-Kurse, um die Sprache zu meistern (2024 Update)
- C++ Vererbung: Public, Protected & Private erklärt
- C# Programmstruktur verstehen: Kernkomponenten & Beispiel
- C# Mehrdimensionale Arrays: 2D Arrays mit Codebeispielen erklärt
- C# Queues meistern: Enqueue, Dequeue und First-In-First-Out Operationen erklärt