Industriële fabricage
Industrieel internet der dingen | Industriële materialen | Onderhoud en reparatie van apparatuur | Industriële programmering |
home  MfgRobots >> Industriële fabricage >  >> Industrial programming >> C Taal

Dynamische Geheugentoewijzing in C: malloc, calloc, realloc en free Beheersen

Voordat we ingaan op dynamische geheugentoewijzing in C, is het essentieel om te begrijpen hoe geheugenbeheer in de taal werkt.

Hoe Geheugenbeheer Werkt in C

Wanneer je een variabele declareert met een primitief type, wijst de compiler automatisch ruimte toe op de stack. Bijvoorbeeld, een float neemt meestal 4 bytes in beslag (platform-afhankelijk). Je kunt dit bevestigen met de sizeof-operator:

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

De output zal zijn:

De grootte van float is 4 bytes

Een array van een gespecificeerde grootte wordt ook achtereenvolgens op de stack toegewezen, met elk element de grootte van zijn type innemend:

#include <stdio.h>
int main() {
    float arr[10];
    printf("De grootte van de float-array met 10 elementen is %d", sizeof(arr));
    return 0;
}

Het resultaat is:

De grootte van de float-array met 10 elementen is 40

Hoewel stack-toewijzing automatisch is, vereisen veel programma's geheugen wiens grootte pas tijdens runtime bekend is. Deze behoefte wordt aangesproken door dynamische geheugentoewijzing, die de heap gebruikt in plaats van de stack.

Dynamische Geheugentoewijzing in C

Dynamische toewijzing omvat handmatig geheugen aanvragen en vrijgeven zoals nodig, met pointers die de toegewezen blokken op de heap bijhouden. De C-standaardbibliotheek biedt diverse functies hiervoor:

  • malloc() – Wijst een aaneengesloten blok bytes toe en retourneert een pointer naar de eerste byte.
  • calloc() – Wijst een array van elementen toe, initialiseert alle bytes op nul, en retourneert een pointer naar het eerste element.
  • realloc() – Past de grootte van een eerder toegewezen blok aan, behoudt de inhoud.
  • free() – Geeft een eerder toegewezen blok vrij aan de heap.

Laten we elke functie in detail verkennen.

malloc() Functie

De malloc()-functie staat voor "memory allocation." Het reserveert een geheugenblok van een gespecificeerde grootte en retourneert een pointer ernaar. De pointer wordt meestal gecast naar het gewenste type:

ptr = (cast_type *) malloc(byte_grootte);

Voorbeeld:

#include <stdlib.h>
int main(){
    int *ptr;
    ptr = malloc(15 * sizeof(*ptr)); /* 15 integers */
    if (ptr != NULL) {
        *(ptr + 5) = 480; /* zesde element */
        printf("Waarde van het 6e integer is %d", *(ptr + 5));
    }
}

Output:

Waarde van het 6e integer is 480

Belangrijke punten:

  1. Gebruik sizeof(*ptr) om de code robuust te maken tegen typewijzigingen.
  2. Controleer op NULL retourwaarde om toewijzingsfouten te detecteren.
  3. Toegewezen geheugen is aaneengesloten; behandel het als een array en gebruik pointer-rekenkunde.

Dynamische toewijzing is niet beperkt tot primitieve typen; het werkt met structuren, karakterarrays, en meer.

free() Functie

Geheugen toegewezen met malloc(), calloc() of realloc() moet expliciet vrijgegeven worden om lekken te voorkomen. De free()-functie voert deze taak uit:

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

Output:

Waarde van het 2e integer is 50

calloc() Functie

calloc() wijst meerdere blokken van gelijke grootte toe en initialiseert elke byte op nul, wat het ideaal maakt voor arrays en structuren die nul-geïnitialiseerd geheugen vereisen:

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

Voorbeeld – optellen van een rekenkundige rij:

#include <stdio.h>
int main() {
    int i, *ptr, som = 0;
    ptr = calloc(10, sizeof(int));
    if (ptr == NULL) {
        printf("Fout! Geheugen niet toegewezen.");
        exit(0);
    }
    for (i = 0; i < 10; ++i) {
        *(ptr + i) = i;
        som += *(ptr + i);
    }
    printf("Som = %d", som);
    free(ptr);
    return 0;
}

Resultaat:

Som = 45

calloc() vs. malloc()

Belangrijke verschillen:

  • Initialisatie: calloc() nul-initialiseert geheugen; malloc() laat het ongeïnitialiseerd (garbage).
  • Gebruik: calloc() is te verkiezen voor arrays of structuren die nul-waarden nodig hebben; malloc() is simpeler wanneer geen initialisatie vereist is.
  • Prestaties: Beiden presteren vergelijkbaar, maar calloc() kan iets langzamer zijn door nul-initialisatie.

realloc() Functie

De realloc()-functie past de grootte van een bestaande toewijzing aan terwijl de inhoud behouden blijft:

ptr = realloc(ptr, nieuwe_grootte);

Voorbeeld – uitbreiden van een string-buffer:

#include <stdio.h>
int main () {
    char *ptr = malloc(10);
    strcpy(ptr, "Programmeren");
    ptr = realloc(ptr, 20); // vergroten
    strcat(ptr, " In 'C'");
    printf("%s, Adres = %u", ptr, ptr);
    free(ptr);
    return 0;
}

Als hertoewijzing mislukt, retourneert realloc() NULL en blijft het originele blok geldig.

Dynamische Arrays

Dynamische arrays laten het aantal elementen tijdens uitvoering groeien, een veelvoorkomend patroon in algoritmen en datastructuren:

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

Resultaat:

arr_dynamisch[0]=0
arr_dynamisch[1]=1
Na realloc
arr_dynamisch[0]=0
arr_dynamisch[1]=1
arr_dynamisch[2]=2
arr_dynamisch[3]=3

Samenvatting

  • Dynamisch geheugen laat je heap-ruimte tijdens runtime toewijzen en vrijgeven.
  • Gebruik malloc() voor enkele blokken, calloc() voor nul-geïnitialiseerde arrays.
  • Controleer altijd op NULL om toewijzingsfouten te detecteren.
  • Vrijgeven met free() om lekken te voorkomen.
  • Vergroot toewijzingen met realloc() wanneer meer ruimte nodig is.
  • Dynamische arrays zijn een krachtig patroon voor flexibele datastructuren.

C Taal

  1. ROM, PROM, EPROM en EEPROM begrijpen: ontwerp, programmeren en identificatie
  2. C# Fundamentals: Invoer en Uitvoer Basis
  3. C# using-statements: imports, aliasen en static directives
  4. C++ Geheugenbeheer meesteren: Expert gebruik van new en delete
  5. Vier bewaarde patronen voor gebruiksgedefinieerde functies in C
  6. Dynamische geheugentoewijzing in C: malloc, calloc, realloc en free onder de knie krijgen
  7. C Standaardbibliotheek-functies onder de knie krijgen: Een praktische gids
  8. C++ Dynamische Array‑Allocatie: Praktische Handleiding met Code‑Voorbeelden
  9. C++ Functies Uitgelegd met Praktische Codevoorbeelden
  10. C-functies: Structuur, declaratie, aanroep en argumenten
  11. Dynamisch Geheugenbeheer in C: calloc, malloc en free uitgelegd