Dynamische Allokation von Structs
Teil des Abschnitts Logic & Flow der C-Journey von Coddy — Lektion 48 von 63.
Bisher haben Sie gelernt, wie man Structs auf dem Stack erstellt – sie existieren innerhalb des Gültigkeitsbereichs, in dem sie deklariert wurden, und werden automatisch bereinigt, wenn dieser Gültigkeitsbereich endet. Aber was ist, wenn ein Struct über seinen ursprünglichen Gültigkeitsbereich hinaus bestehen bleiben muss oder wenn Sie zur Kompilierzeit noch nicht wissen, wie viele Structs Sie benötigen werden?
Hier kommt die dynamische Speicherzuweisung ins Spiel. Man kann malloc() verwenden, um Structs auf dem Heap zu erstellen, genau wie für jeden anderen Datentyp. Der Hauptunterschied besteht darin, dass dynamisch allokierte Structs so lange im Speicher bleiben, bis man sie explizit mit free() freigibt.
Hier ist die Syntax für die dynamische Allokation eines Structs:
struct Point *ptr = malloc(sizeof(struct Point));Dies reserviert genügend Speicher auf dem Heap für ein Point-Struct und gibt einen Pointer auf diesen Speicher zurück. Sie können dann den Pfeiloperator verwenden, um auf die Struct-Member zuzugreifen und diese zu ändern:
ptr->x = 10;
ptr->y = 20;Denken Sie daran, immer zu prüfen, ob malloc() erfolgreich war (nicht NULL zurückgegeben hat) und free(ptr) aufzurufen, wenn Sie mit dem Struct fertig sind, um Speicherlecks zu vermeiden. Diese Technik ist essenziell für die Erstellung flexibler Programme, die Datenstrukturen zur Laufzeit erstellen und verwalten können.
Aufgabe
EinfachErstellen Sie ein C-Programm, das die dynamische Allokation von Structs mit malloc() demonstriert. Ihr Programm sollte:
- Definieren Sie ein
structnamensCarmit den folgenden Mitgliedern:- Ein Integer
year, um das Herstellungsjahr zu speichern - Ein Zeichen-Array (char array)
brandmit der Größe 20, um die Automarke zu speichern - Ein Zeichen-Array (char array)
modelmit der Größe 25, um das Automodell zu speichern - Ein Float
price, um den Autopreis zu speichern - Ein Integer
mileage, um den Kilometerstand des Autos zu speichern
- Ein Integer
- Deklarieren Sie in der main-Funktion einen Pointer auf ein
Car-Struct namenscarPtr - Verwenden Sie
malloc(), um dynamisch Speicher für einCar-Struct zu allokieren, und weisen Sie die zurückgegebene AdressecarPtrzu - Überprüfen Sie, ob die Speicherallokation erfolgreich war:
- Wenn
carPtrgleichNULList, geben SieMemory allocation failedaus und beenden Sie das Programm - Wenn die Allokation erfolgreich war, geben Sie
Memory allocation successfulaus
- Wenn
- Lesen Sie die folgenden Eingabewerte ein und weisen Sie diese den Struct-Mitgliedern unter Verwendung des Pfeil-Operators zu:
- Lesen Sie einen Integer für das Jahr ein und weisen Sie ihn über
carPtr->yearzu - Lesen Sie einen String für die Marke ein und weisen Sie ihn über
carPtr->brandzu - Lesen Sie einen String für das Modell ein und weisen Sie ihn über
carPtr->modelzu - Lesen Sie einen Float für den Preis ein und weisen Sie ihn über
carPtr->pricezu - Lesen Sie einen Integer für den Kilometerstand ein und weisen Sie ihn über
carPtr->mileagezu
- Lesen Sie einen Integer für das Jahr ein und weisen Sie ihn über
- Führen Sie nach dem Einlesen aller Werte die folgenden Berechnungen unter Verwendung des Pfeil-Operators durch:
- Berechnen Sie das Alter des Autos, indem Sie das Jahr von 2024 subtrahieren:
int age = 2024 - carPtr->year; - Berechnen Sie die Abschreibungsrate basierend auf dem Alter: Wenn das Alter größer als 10 ist, setzen Sie die Abschreibung auf 0.6, andernfalls auf 0.8
- Berechnen Sie den aktuellen Wert:
carPtr->price * depreciation
- Berechnen Sie das Alter des Autos, indem Sie das Jahr von 2024 subtrahieren:
- Geben Sie die Autoinformationen unter Verwendung des Pfeil-Operators in genau diesem Format aus:
Car Information:Year: [year]Brand: [brand]Model: [model]Original Price: [price]Mileage: [mileage]Age: [age] yearsCurrent Value: [current_value]
- Geben Sie den dynamisch allokierten Speicher mit
free(carPtr)frei - Geben Sie
Memory freed successfullyaus
Diese Herausforderung testet Ihr Verständnis der dynamischen Struct-Allokation mit malloc(), der Überprüfung auf Allokationsfehler, des Zugriffs auf Struct-Mitglieder über Pointer mit dem Pfeil-Operator und der ordnungsgemäßen Freigabe von allokiertem Speicher mit free(). Sie üben den vollständigen Lebenszyklus der dynamischen Speicherverwaltung mit Structs.
Spickzettel
Verwenden Sie malloc(), um Structs dynamisch auf dem Heap zu reservieren:
struct Point *ptr = malloc(sizeof(struct Point));Greifen Sie über Pointer unter Verwendung des Pfeil-Operators auf Struct-Member zu:
ptr->x = 10;
ptr->y = 20;Prüfen Sie immer, ob malloc() erfolgreich war, und geben Sie den Speicher frei, wenn Sie fertig sind:
if (ptr == NULL) {
// Behandle Speicherreservierungsfehler
}
// Verwende das Struct...
free(ptr);Probier es selbst
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// TODO: Definieren Sie hier die Car-Struktur
int main() {
// TODO: Deklarieren Sie einen Zeiger auf die Car-Struktur namens carPtr
// TODO: Verwenden Sie malloc(), um Speicher für eine Car-Struktur zu reservieren
// TODO: Überprüfen Sie, ob die Speicherreservierung erfolgreich war
// Eingabewerte einlesen
int year, mileage;
char brand[20], model[25];
float price;
scanf("%d", &year);
scanf("%s", brand);
scanf("%s", model);
scanf("%f", &price);
scanf("%d", &mileage);
// TODO: Weisen Sie die Eingabewerte den Struktur-Elementen mit dem Pfeil-Operator zu
// TODO: Berechnen Sie Alter, Wertverlust und aktuellen Wert
// TODO: Geben Sie die Autoinformationen im erforderlichen Format aus
// TODO: Geben Sie den reservierten Speicher frei und geben Sie eine Erfolgsmeldung aus
return 0;
}Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in Logic & Flow
1Zeiger-Grundlagen
Was ist ein Zeiger?Zeiger deklarierenDer Adressoperator (&)Der Dereferenzierungsoperator (*)NULL-ZeigerZusammenfassung: Zeiger-Grundlagen4Projekt: Einfaches Text-Tool
ProjektübersichtZeichen zählen2Pointer und Arrays
Array-Namen als PointerArray-Elemente - PointerPointer-ArithmetikPointer vergleichenWiederholung: Array-Durchlauf mit Pointern5Zeiger und Funktionen
Wertübergabe (Pass-by-Value)Zeiger an Funktionen übergebenVariablen über Zeiger ändernEin klassisches Beispiel: SwapArrays an Funktionen übergebenZusammenfassung: Zeiger als Funktionsargumente8Structs und Zeiger
Zeiger auf StructsDer Pfeiloperator (->)Structs per Wert übergebenÜbergabe von Struct-ZeigernDynamische Allokation von StructsZusammenfassung: Struct ändern - Ptr11Finale Wiederholungsaufgaben
Wiederholung: Dynamische String-KonkatenationWiederholung: Array von StructsWiederholung: Wortfrequenz-Zähler3Character-Arrays und Strings
Strings als char-ArraysDer Null-TerminatorString-Eingabe mit scanfVerwendung von strlen()Verwendung von strcpy()Verwendung von strcat()Verwendung von strcmp()Zusammenfassung: Grundlegende String-Funktionen