calloc()-Funktion in der C-Bibliothek mit Programm BEISPIEL

⚡ Intelligente Zusammenfassung

Die Funktion calloc() in C reserviert mehrere zusammenhängende Speicherblöcke auf dem Heap und initialisiert jedes Byte mit Null. Sie gibt einen Void-Pointer zurück, mit dem Programme zur Laufzeit saubere, sofort einsatzbereite Arrays und Datenstrukturen erstellen können.

  • 🧠 Nullinitialisierter Speicher: calloc() setzt alle zugewiesenen Bytes auf Null, im Gegensatz zu malloc(), das unvorhersehbare Speicherreste hinterlässt.
  • 📦 Zwei Argumente: calloc(n, size) reserviert n Blöcke der angegebenen Größe in einem zusammenhängenden Bereich.
  • ⚠️ NULL-Prüfung: Bei einer fehlgeschlagenen Speicherzuweisung wird ein NULL-Zeiger zurückgegeben. Überprüfen Sie daher das Ergebnis, bevor Sie es verwenden.
  • 🆚 calloc vs malloc: Verwenden Sie calloc() für saubere, mit Nullen initialisierte Arrays und malloc(), wenn die Geschwindigkeit wichtiger ist als die Initialisierung.
  • 🧹 Speicher freigeben: Um Speicherlecks zu vermeiden, wird jeder calloc()-Block mit free() freigegeben.
  • 🤖 KI-Unterstützung: KI-Assistenten und GitHub Copilot entwerfen calloc()-Aufrufe und kennzeichnen fehlende free()-Anweisungen.

calloc()-Funktion in C

Was ist Calloc in C?

Die Funktion `calloc()` in C dient der Zuweisung mehrerer gleich großer Speicherblöcke. Sie ermöglicht die dynamische Speicherverwaltung komplexer Datenstrukturen wie Arrays und Strukturen und gibt einen `void`-Zeiger auf den Speicher zurück. `calloc` steht für zusammenhängende Speicherzuweisung.

Malloc-Funktion wird verwendet, um einen einzelnen Block Speicherplatz zuzuweisen, während die Calloc-Funktion in C verwendet wird, um mehrere Blöcke Speicherplatz zuzuweisen. Jeder vom Calloc in der C-Programmierung zugewiesene Block hat die gleiche Größe.

Warum sollte man calloc() in C verwenden?

Herkömmliche Variablen und Arrays fester Größe legen ihre Dimensionen beim Kompilieren des Programms fest. Dies führt zu Speicherplatzverschwendung, wenn weniger Elemente benötigt werden, und zu einem Fehler, wenn mehr Elemente erforderlich sind. `calloc()` beseitigt diese Einschränkung, indem es Speicher zur Laufzeit reserviert und – anders als `malloc()` – jedes Byte auf Null setzt, bevor der Speicherblock zurückgegeben wird. Daher ist `calloc()` die optimale Wahl, wenn ein Programm einen sauberen, vorhersehbaren Speicherbereich für ein Array oder eine Struktur benötigt, deren Größe erst während der Programmausführung bekannt ist.

Die dynamische Speicherverwaltung mit calloc() eignet sich für verschiedene gängige Situationen:

  • Numerische Arrays, die bei Null beginnen sollen, wie z. B. Zähler, Histogramme oder laufende Akkumulatoren.
  • Datenstrukturen, bei denen Restwerte zu subtilen, schwer zu erkennenden Problemen führen würdentracund Fehler.
  • Buffers, deren Länge von Benutzereingaben oder einer während der Programmausführung gelesenen Datei abhängt.
  • Die Blöcke sind zu groß für den begrenzten Stack, da calloc() vom viel größeren Heap liest.

Da der reservierte Block zusammenhängend und bereits mit Nullen gefüllt ist, kann er ohne separate Initialisierungsschleife sofort als einsatzbereites Array behandelt werden.

calloc() Syntax:

ptr = (cast_type *) calloc (n, size);
  • Das obige Anweisungsbeispiel für calloc in C wird verwendet, um n Speicherblöcke derselben Größe zuzuweisen.
  • Nachdem der Speicherplatz zugewiesen wurde, werden alle Bytes auf Null initialisiert.
  • Das Zeiger zurückgegeben wird, welches aktuell das erste Byte des zugewiesenen Speicherplatzes ist.

Immer wenn bei der Zuweisung von Speicherplatz ein Fehler auftritt, beispielsweise aufgrund von Speichermangel, wird ein Nullzeiger zurückgegeben, wie im folgenden Calloc-Beispiel gezeigt.

So verwenden Sie Calloc

Das folgende Calloc-Programm in C berechnet die Summe einer arithmetischen Folge.

#include <stdio.h>
    int main() {
        int i, * ptr, sum = 0;
        ptr = calloc(10, sizeof(int));
        if (ptr == NULL) {
            printf("Error! memory not allocated.");
            exit(0);
        }
        printf("Building and calculating the sequence sum of the first 10 terms \ n ");
        for (i = 0; i < 10; ++i) { * (ptr + i) = i;
            sum += * (ptr + i);
        }
        printf("Sum = %d", sum);
        free(ptr);
        return 0;
    }

Ergebnis des Aufrufs im C-Beispiel:

 
Building and calculating the sequence sum of the first 10 terms
Sum = 45

Unterschied zwischen calloc() und malloc()

calloc() und malloc() reservieren beide Speicher auf dem Heap und geben beide einen void-Pointer oder im Fehlerfall NULL zurück, unterscheiden sich aber in drei praktischen Punkten, die darüber entscheiden, welche Funktion verwendet werden soll.

  • Initialisierung: calloc() setzt jedes Byte im neuen Block auf Null, während malloc() den Inhalt uninitialisiert lässt, sodass ein malloc()-Block unvorhersehbaren Datenmüll enthält, bis das Programm hineinschreibt.
  • Argumente: calloc() benötigt zwei Argumente, die Anzahl der Elemente und die Größe jedes Elements, geschrieben calloc(n, size); malloc() benötigt ein einzelnes Argument, die Gesamtanzahl der Bytes, geschrieben malloc(n * size).
  • Geschwindigkeit: malloc() ist geringfügig schneller, da es den Nullsetzungsschritt überspringt. Deshalb wird es oft von Code bevorzugt, der den Speicher sofort überschreibt.

Beide Funktionen sind in stdlib.h deklariert und geben ihren Speicher mit derselben Funktion `free()` frei. Verwenden Sie `calloc()`, wenn ein sauberer, mit Nullen initialisierter Speicherblock wichtig ist, und `malloc()`, wenn maximale Geschwindigkeit Priorität hat und das Programm die Initialisierung selbst übernimmt.

Wie man den von calloc() allokierten Speicher freigibt

Der von `calloc()` reservierte Speicher verbleibt im Heap und wird nicht automatisch freigegeben. Wenn ein Programm ständig Speicher allokiert, ohne ihn freizugeben, verbraucht es nach und nach den gesamten verfügbaren Speicher – ein Fehler, der als Speicherleck bekannt ist. Die Funktion `free()` gibt einen freigegebenen Speicherblock an das System zurück, sodass der Speicherplatz für spätere Speicherbelegungen wiederverwendet werden kann.

Die Funktion free() nimmt ein einzelnes Argument entgegen, den von calloc() zurückgegebenen Zeiger, und gibt den gesamten Block auf einmal frei:

int *ptr;
ptr = calloc(10, sizeof(int));
if (ptr != NULL) {
    /* use the allocated memory here */
    free(ptr);   /* release the block */
    ptr = NULL;  /* avoid a dangling pointer */
}

Befolgen Sie diese Regeln, um den Speicher von calloc() sicher zu verwalten:

  • Rufen Sie free() genau einmal für jeden erfolgreichen calloc() auf; das zweimalige Freigeben desselben Blocks führt zu undefiniertem Verhalten.
  • Setzen Sie den Zeiger nach der Freigabe auf NULL, damit er nicht als hängender Zeiger wiederverwendet werden kann.
  • Verwenden Sie niemals free() für einen Zeiger, den calloc() nicht zurückgegeben hat, einschließlich eines Zeigers, der durch Zeigerarithmetik verschoben wurde.
  • Jede Speicherzuweisung muss mit einer Freigabe einhergehen, bevor der Zeiger seinen Gültigkeitsbereich verlässt.

Da calloc() und malloc() beide auf denselben Heap zugreifen, ist die Freigabedisziplin für beide Funktionen identisch: ein free()-Aufruf für jede erfolgreiche Speicherbelegung und anschließend kein Zugriff mehr auf den Speicherblock. Keeping Das Ausgewogene Zuweisen und Freigeben von Speicher ist die Kerngewohnheit der manuellen Speicherverwaltung in C und verhindert sowohl Speicherlecks als auch Abstürze, die durch die Wiederverwendung bereits freigegebenen Speichers verursacht werden.

Häufig gestellte Fragen

Die Funktion calloc() ist in der Headerdatei stdlib.h der Standardbibliothek deklariert, daher fügen Sie #include hinzu. am Anfang der Quelldatei. Ohne diese Angabe kann der Compiler eine Warnung wegen einer impliziten Deklaration ausgeben und den zurückgegebenen Zeiger falsch interpretieren.

Kann der Heap die Anfrage nicht erfüllen, gibt `calloc()` einen NULL-Zeiger anstelle einer gültigen Adresse zurück. Vergleichen Sie das Ergebnis immer mit NULL, bevor Sie es verwenden, da das Dereferenzieren von NULL undefiniertes Verhalten verursacht und in der Regel zum Absturz des Programms führt.

Ja. `calloc()` funktioniert mit jedem Typ, einschließlich Strukturen und Arrays von Strukturen, indem man die Anzahl der Elemente und `sizeof(struct)` übergibt. Alle Elemente werden mit Nullen initialisiert, wodurch ein sauberer Ausgangszustand ohne manuelle Initialisierungsschleife erreicht wird.

Ja. `realloc()` akzeptiert jeden von `calloc()` oder `malloc()` zurückgegebenen Zeiger und vergrößert oder verkleinert den Speicherblock, wobei die vorhandenen Daten erhalten bleiben. Neu hinzugefügte Bytes werden nicht mit Nullen initialisiert; initialisieren Sie diese daher gegebenenfalls selbst.

Das Ergebnis ist implementierungsabhängig: `calloc()` kann `NULL` oder einen eindeutigen Zeiger zurückgeben, der nicht dereferenziert werden kann, aber sicher an `free()` übergeben werden kann. Behandeln Sie beide Ergebnisse als „kein nutzbarer Speicher“ und vermeiden Sie es, daraus zu lesen.

Die Funktion `calloc()` reserviert einen zusammenhängenden Speicherbereich, der groß genug für alle angeforderten Elemente ist, sodass diese wie Array-Zellen aneinandergereiht werden. Der Name spiegelt diesen zusammenhängenden, gelöschten Block wider und ermöglicht so zuverlässige Zeigerarithmetik im Speicher.

Ja. KI-Programmierassistenten entwerfen calloc()-Aufrufe, fügen NULL-Prüfungen hinzu und kennzeichnen fehlende free()-Aufrufe oder Speicherlecks. Außerdem erklären sie die Zeigerarithmetik. Kompilieren und testen Sie den generierten Code immer, bevor Sie ihn in der Produktion einsetzen.

GitHub-Copilot schlägt calloc(), sizeof() und passende free()-Zeilen aus einem Kommentar vor, der Ihre Absicht beschreibt. RevPrüfen Sie vor dem Kompilieren jeden Vorschlag auf fehlende NULL-Prüfungen und Speicherlecks.

Fassen Sie diesen Beitrag mit folgenden Worten zusammen: