Allokation mit calloc()
Teil des Abschnitts Logic & Flow der C-Journey von Coddy — Lektion 36 von 63.
Während malloc() die gebräuchlichste Funktion für die dynamische Speicherbelegung ist, bietet C eine weitere nützliche Alternative: calloc(). Die Funktion calloc(), die für „contiguous allocation“ steht, bietet eine bequeme Möglichkeit, Speicher für Arrays mit einem wichtigen zusätzlichen Vorteil zu reservieren.
Im Gegensatz zu malloc(), das ein einzelnes Argument (Gesamt-Bytes) entgegennimmt, benötigt calloc() zwei Argumente: die Anzahl der Elemente, die Sie reservieren möchten, und die Größe jedes Elements. Dies macht es besonders intuitiv bei der Arbeit mit Arrays. Zum Beispiel:
#include <stdlib.h>
// Allocate space for 5 integers using calloc()
int *arr = (int*)calloc(5, sizeof(int));
// This is equivalent to: malloc(5 * sizeof(int))Der entscheidende Vorteil von calloc() ist, dass es den gesamten zugewiesenen Speicher automatisch mit Null initialisiert. Wenn Sie malloc() verwenden, enthält der zugewiesene Speicher beliebige Zufallswerte, die zuvor dort gespeichert waren, aber calloc() garantiert, dass jedes Byte auf Null gesetzt wird. Das bedeutet, dass alle Integer 0 sind, alle Floats 0.0 und alle Pointer NULL.
Wie malloc() gibt calloc() einen Zeiger auf den reservierten Speicher zurück oder NULL, falls die Reservierung fehlschlägt. Daher sollten Sie immer auf einen Reservierungsfehler prüfen und daran denken, den Speicher mit free() freizugeben, wenn Sie ihn nicht mehr benötigen.
Aufgabe
EinfachSchreiben Sie ein C-Programm, das die Verwendung von calloc() für die dynamische Speicherallokation mit automatischer Null-Initialisierung demonstriert. Ihr Programm sollte:
- Einen Ganzzahlwert
sizevom Benutzer einlesen, der die Anzahl der zu allokierenden Ganzzahlen darstellt calloc()verwenden, um dynamisch Speicher für ein Array vonsizeGanzzahlen zu allokieren- Überprüfen, ob die Speicherallokation erfolgreich war - falls sie fehlschlägt, geben Sie
Memory allocation failed!aus und beenden Sie das Programm - Wenn die Allokation erfolgreich ist, geben Sie
Memory allocated and initialized to zero!aus - Geben Sie alle Initialwerte im Array aus, um zu demonstrieren, dass sie Null sind, im Format:
Initial values: [value1] [value2] [value3] ... - Lesen Sie
sizeGanzzahlwerte vom Benutzer ein und speichern Sie diese im allokierten Array - Geben Sie alle aktualisierten Werte im Format aus:
Updated values: [value1] [value2] [value3] ... - Berechnen und geben Sie die Summe aller Werte im Format aus:
Sum: [value] - Verwenden Sie
free(), um den Speicher freizugeben - Geben Sie
Memory freed!aus, um die Bereinigung zu bestätigen
Denken Sie daran, den Header <stdlib.h> einzubinden, um calloc() und free() zu verwenden. Diese Herausforderung demonstriert den entscheidenden Vorteil von calloc() gegenüber malloc(): die automatische Initialisierung des gesamten allokierten Speichers auf Null.
Zum Beispiel, wenn die Eingabe wie folgt lautet:
3
10 20 30Sollte Ihre Ausgabe wie folgt aussehen:
Memory allocated and initialized to zero!
Initial values: 0 0 0
Updated values: 10 20 30
Sum: 60
Memory freed!Diese Herausforderung verdeutlicht, wie calloc() einen sauberen, vorhersehbaren Ausgangszustand für Ihre dynamisch allokierten Arrays bietet und die unvorhersehbaren Garbage-Werte eliminiert, die malloc() hinterlassen könnte.
Spickzettel
Die Funktion calloc() bietet dynamische Speicherallokation mit automatischer Null-Initialisierung.
Syntax:
void* calloc(size_t num_elements, size_t element_size);Wesentliche Unterschiede zu malloc():
- Erwartet zwei Argumente: Anzahl der Elemente und Größe jedes Elements
- Initialisiert den gesamten reservierten Speicher automatisch mit Null
- Intuitiver für die Allokation von Arrays
Beispiel für die Verwendung:
#include <stdlib.h>
// Allocate space for 5 integers using calloc()
int *arr = (int*)calloc(5, sizeof(int));
// This is equivalent to: malloc(5 * sizeof(int))
// But all values are guaranteed to be 0Wie malloc() gibt auch calloc() einen Zeiger auf den reservierten Speicher zurück oder NULL, falls die Allokation fehlschlägt. Prüfen Sie immer auf Allokationsfehler und verwenden Sie free(), um den Speicher freizugeben, wenn er nicht mehr benötigt wird.
Probier es selbst
#include <stdio.h>
#include <stdlib.h>
int main() {
int size;
// Lies die Größe des Arrays ein
scanf("%d", &size);
// TODO: Schreibe deinen Code unten
// Verwende calloc(), um Speicher für das Array zu reservieren
// Überprüfe, ob die Speicherreservierung erfolgreich war
// Gib die Initialwerte aus (sollten Null sein)
// Lies die Eingabewerte ein und speichere sie
// Gib die aktualisierten Werte aus
// Berechne und gib die Summe aus
// Gib den reservierten Speicher frei
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