Industrielle Fertigung
Industrielles Internet der Dinge | Industrielle Materialien | Gerätewartung und Reparatur | Industrielle Programmierung |
home  MfgRobots >> Industrielle Fertigung >  >> Industrial programming >> C Sprache

Dynamische Speicherallokation in C: malloc, calloc, realloc und free meistern

Bevor wir in die dynamische Speicherallokation in C eintauchen, ist es essenziell zu verstehen, wie Speicherverwaltung in der Sprache funktioniert.

Wie Speicherverwaltung in C funktioniert

Wenn Sie eine Variable mit einem primitiven Typ deklarieren, allokiert der Compiler automatisch Speicherplatz dafür auf dem Stack. Zum Beispiel belegt ein float typischerweise 4 Bytes (plattformabhängig). Dies können Sie mit dem sizeof-Operator bestätigen:

#include <stdio.h>
int main() {
    float x;
    printf("The size of float is %d bytes", sizeof(x));
    return 0;
}

Ausgabe:

The size of float is 4 bytes

Ein Array fester Größe wird ebenfalls kontiguierlich auf dem Stack allokiert, wobei jedes Element die Größe seines Typs einnimmt:

#include <stdio.h>
int main() {
    float arr[10];
    printf("The size of the float array with 10 elements is %d", sizeof(arr));
    return 0;
}

Ergebnis:

The size of the float array with 10 elements is 40

Während Stack-Allokation automatisch ist, benötigen viele Programme Speicher, dessen Größe erst zur Laufzeit bekannt ist. Dieser Bedarf wird durch dynamische Speicherallokation gedeckt, die den Heap statt des Stacks nutzt.

Dynamische Speicherallokation in C

Dynamische Allokation beinhaltet manuelles Anfordern und Freigeben von Speicher nach Bedarf, wobei Zeiger die allokierten Blöcke auf dem Heap verfolgen. Die C-Standardbibliothek stellt mehrere Funktionen dafür bereit:

Lassen Sie uns jede Funktion im Detail betrachten.

malloc() Funktion

Die malloc()-Funktion steht für „memory allocation“. Sie reserviert einen Speicherblock der angegebenen Größe und gibt einen Zeiger darauf zurück. Der Zeiger wird typischerweise in den gewünschten Typ gecastet:

ptr = (cast_type *) malloc(byte_size);

Beispiel:

#include <stdlib.h>
int main() {
    int *ptr;
    ptr = malloc(15 * sizeof(*ptr)); /* 15 Integers */
    if (ptr != NULL) {
        *(ptr + 5) = 480; /* sechstes Element */
        printf("Value of the 6th integer is %d", *(ptr + 5));
    }
}

Ausgabe:

Value of the 6th integer is 480

Wichtige Punkte:

  1. Nutzen Sie sizeof(*ptr), um Code robust gegen Typänderungen zu machen.
  2. Prüfen Sie auf NULL-Rückgabe, um Allokationsfehler zu erkennen.
  3. Allokierter Speicher ist kontiguierlich; behandeln Sie ihn wie ein Array und nutzen Sie Zeigerarithmetik.

Dynamische Allokation ist nicht auf primitive Typen beschränkt; sie funktioniert mit Strukturen, Zeichen-Arrays und mehr.

free() Funktion

Mit malloc(), calloc() oder realloc() allokierter Speicher muss explizit freigegeben werden, um Leaks zu vermeiden. free() erledigt dies:

#include <stdio.h>
int main() {
    int* ptr = malloc(10 * sizeof(*ptr));
    if (ptr != NULL) {
        *(ptr + 2) = 50;
        printf("Value of the 2nd integer is %d", *(ptr + 2));
    }
    free(ptr);
}

Ausgabe:

Value of the 2nd integer is 50

calloc() Funktion

calloc() allokiert mehrere Blöcke gleicher Größe und initialisiert jedes Byte auf Null, ideal für Arrays und Strukturen, die nullten Speicher benötigen:

ptr = (cast_type *) calloc(n, size);

Beispiel – 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);
    }
    for (i = 0; i < 10; ++i) {
        *(ptr + i) = i;
        sum += *(ptr + i);
    }
    printf("Sum = %d", sum);
    free(ptr);
    return 0;
}

Ergebnis:

Sum = 45

calloc() vs. malloc()

Wesentliche Unterschiede:

realloc() Funktion

Die realloc()-Funktion ändert die Größe einer existierenden Allokation bei Beibehaltung des Inhalts:

ptr = realloc(ptr, newsize);

Beispiel – String-Puffer erweitern:

#include <stdio.h>
#include <string.h>
int main() {
    char *ptr = malloc(10);
    strcpy(ptr, "Programming");
    ptr = realloc(ptr, 20); // vergrößern
    strcat(ptr, " In 'C'");
    printf("%s, Address = %u", ptr, ptr);
    free(ptr);
    return 0;
}

Fällt Reallokation fehl, gibt realloc() NULL zurück und der ursprüngliche Block bleibt gültig.

Dynamische Arrays

Dynamische Arrays erlauben, die Elementanzahl zur Laufzeit wachsen zu lassen – ein gängiges Muster in Algorithmen und Datenstrukturen:

#include <stdio.h>
int main() {
    int *arr_dynamic = NULL;
    int elements = 2, i;
    arr_dynamic = calloc(elements, sizeof(int));
    for (i = 0; i < elements; i++) arr_dynamic[i] = i;
    for (i = 0; i < elements; i++) printf("arr_dynamic[%d]=%d\n", i, arr_dynamic[i]);
    elements = 4;
    arr_dynamic = realloc(arr_dynamic, elements * sizeof(int));
    printf("After realloc\n");
    for (i = 2; i < elements; i++) arr_dynamic[i] = i;
    for (i = 0; i < elements; i++) printf("arr_dynamic[%d]=%d\n", i, arr_dynamic[i]);
    free(arr_dynamic);
}

Ergebnis:

arr_dynamic[0]=0 arr_dynamic[1]=1
After realloc
arr_dynamic[0]=0 arr_dynamic[1]=1 arr_dynamic[2]=2 arr_dynamic[3]=3

Zusammenfassung

C Sprache

  1. ROM, PROM, EPROM und EEPROM verstehen: Design, Programmierung und Identifikation
  2. C# Grundlagen: Eingabe und Ausgabe Essentials
  3. C# using-Anweisungen meistern: Importe, Aliase und statische Direktiven
  4. C++ Speicherverwaltung meistern: Experten-Einsatz von new und delete
  5. Vier bewährte Muster für benutzerdefinierte Funktionen in C
  6. Dynamische Speicherallokation in C: malloc, calloc, realloc & free meistern
  7. C-Standardbibliothek-Funktionen meistern: Praxisleitfaden
  8. C++ Dynamische Array‑Allokation: Praktischer Leitfaden mit Code‑Beispielen
  9. C++-Funktionen erklärt: Mit praktischen Code-Beispielen
  10. C-Funktionen meistern: Struktur, Deklaration & Best Practices