Dynamisk minnesallokering i C med malloc(), calloc()-funktioner

Innan du lär dig C Dynamic Memory allocation, låt oss förstå:

Hur fungerar minneshantering i C?

När du deklarerar en variabel med en grundläggande datatyp, allokerar C-kompilatorn automatiskt minnesutrymme för variabeln i en minnespool som kallas stapel.

Till exempel tar en flytvariabel vanligtvis 4 byte (enligt plattformen) när den deklareras. Vi kan verifiera denna information med hjälp av storlek av operatör som visas i exemplet nedan

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

Utgången kommer att vara:

 The size of float is 4 bytes

Dessutom tilldelas en array med en specificerad storlek i angränsande minnesblock, varje block har storleken för ett element:

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

Resultatet är:

 The size of the float array with 10 element is 40

Som vi har lärt dig hittills, när du deklarerar en grundläggande datatyp eller en array, hanteras minnet automatiskt. Det finns dock en process för att allokera minne i C som gör att du kan implementera ett program där arraystorleken är obestämd tills du kör ditt program (runtime). Denna process kallas "Dynamisk minnesallokering. "

Dynamisk minnesallokering i C

Dynamisk minnesallokering är manuell tilldelning och frigöring av minne enligt dina programmeringsbehov. Dynamiskt minne hanteras och serveras med pekare som pekar på det nytilldelade minnesutrymmet i ett område som vi kallar högen.

Nu kan du skapa och förstöra en rad element dynamiskt under körning utan problem. Sammanfattningsvis använder den automatiska minneshanteringen stacken, och C Dynamic Memory Allocation använder högen.

De biblioteket har funktioner som ansvarar för Dynamic Memory Management.

Funktion Syfte
malloc () Tilldelar minnet av begärd storlek och returnerar pekaren till den första byten av
tilldelat utrymme.
calloc() Tilldelar utrymme för element i en array. Initierar elementen till noll och returnerar en pekare till minnet.
realloc () Den används för att ändra storleken på tidigare tilldelat minnesutrymme.
Fri() Frigör eller tömmer det tidigare tilldelade minnesutrymmet.

Låt oss diskutera ovanstående funktioner med deras tillämpning

malloc() funktion i C

Funktionen C malloc() står för minnesallokering. Det är en funktion som används för att tilldela ett minnesblock dynamiskt. Den reserverar minnesutrymme av specificerad storlek och returnerar nollpekaren som pekar till minnesplatsen. Pekaren som returneras är vanligtvis av typen void. Det betyder att vi kan tilldela C malloc()-funktionen till vilken pekare som helst.

Syntax för malloc() Funktion:

ptr = (cast_type *) malloc (byte_size);

Här,

  • ptr är en pekare av cast_type.
  • Funktionen C malloc() returnerar en pekare till det tilldelade minnet av byte_size.

Exempel på malloc():

Example: ptr = (int *) malloc (50)

När denna sats exekveras framgångsrikt, reserveras ett minnesutrymme på 50 byte. Adressen för den första byten av reserverat utrymme tilldelas pekaren ptr av typen int.

Tänk på ett annat exempel:

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

Produktion:

Value of the 6th integer is 480

C malloc() Funktion

  1. Lägg märke till att sizeof(*ptr) användes istället för sizeof(int) för att göra koden mer robust när *ptr-deklarationen typcastas till en annan datatyp senare.
  2. Tilldelningen kan misslyckas om minnet inte räcker till. I det här fallet returnerar den en NULL-pekare. Så du bör inkludera kod för att leta efter en NULL-pekare.
  3. Tänk på att det tilldelade minnet är sammanhängande och det kan behandlas som en array. Vi kan använda pekaritmetik för att komma åt arrayelementen istället för att använda parenteser [ ]. Vi rekommenderar att du använder + för att hänvisa till arrayelement eftersom användning av inkrementering ++ eller += ändrar adressen som lagras av pekare.

Malloc()-funktionen kan också användas med teckendatatypen såväl som komplexa datatyper som strukturer.

free() funktion i C

Minnet för variabler avallokeras automatiskt vid kompilering. Vid dynamisk minnesallokering måste du deallokera minne explicit. Om du inte gör det kan du stöta på ett minnesfel.

Det fria() funktionen kallas för att frigöra/avallokera minne i C. Genom att frigöra minne i ditt program gör du mer tillgängligt för användning senare.

Till exempel:

#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);
}

Produktion:

 Value of the 2nd integer is 50

calloc() funktion i C

Funktionen C calloc() står för kontinuerlig allokering. Denna funktion används för att allokera flera minnesblock. Det är en dynamisk minnesallokeringsfunktion som används för att allokera minnet till komplexa datastrukturer som arrayer och strukturer.

Malloc()-funktionen används för att allokera ett enda block av minnesutrymme medan calloc() i C används för att allokera flera block av minnesutrymme. Varje block som allokeras av calloc()-funktionen är av samma storlek.

Syntax för calloc() Funktion:

ptr = (cast_type *) calloc (n, size);
  • Ovanstående sats används för att allokera n minnesblock av samma storlek.
  • Efter att minnesutrymmet har allokerats, initialiseras alla byte till noll.
  • Pekaren som för närvarande befinner sig vid den första byten av det tilldelade minnesutrymmet returneras.

Närhelst det uppstår ett fel vid allokering av minnesutrymme, såsom brist på minne, returneras en nollpekare.

Exempel på calloc():

Programmet nedan beräknar summan av en aritmetisk sekvens.

#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;
    }

Resultat:

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

calloc() vs. malloc(): Nyckelskillnader

Följande är nyckelskillnaden mellan malloc() kontra calloc() i C:

Calloc()-funktionen är i allmänhet mer lämplig och effektiv än malloc()-funktionen. Medan båda funktionerna används för att allokera minnesutrymme, kan calloc() allokera flera block samtidigt. Du behöver inte begära ett minnesblock varje gång. Calloc()-funktionen används i komplexa datastrukturer som kräver större minnesutrymme.

Minnesblocket som allokeras av en calloc() i C initieras alltid till noll medan det i funktionen malloc() i C alltid innehåller ett skräpvärde.

realloc() funktion i C

Med hjälp av C realloc () funktion kan du lägga till mer minnesstorlek till redan tilldelat minne. Det utökar det aktuella blocket samtidigt som det ursprungliga innehållet lämnas som det är. realloc() i C står för omallokering av minne.

realloc() kan också användas för att minska storleken på det tidigare allokerade minnet.

Syntax för realloc() Funktion:

ptr = realloc (ptr,newsize);

Ovanstående sats allokerar ett nytt minnesutrymme med en specificerad storlek i variabeln nyhetsstorlek. Efter att ha utfört funktionen kommer pekaren att återgå till den första byten i minnesblocket. Den nya storleken kan vara större eller mindre än det tidigare minnet. Vi kan inte vara säkra på att om det nyligen allokerade blocket kommer att peka på samma plats som det föregående minnesblocket. Denna funktion kommer att kopiera alla tidigare data i den nya regionen. Det ser till att data förblir säkra.

Exempel på realloc():

#include <stdio.h>
int main () {
   char *ptr;
   ptr = (char *) malloc(10);
   strcpy(ptr, "Programming");
   printf(" %s,  Address = %u\n", ptr, ptr);

   ptr = (char *) realloc(ptr, 20); //ptr is reallocated with new size
   strcat(ptr, " In 'C'");
   printf(" %s,  Address = %u\n", ptr, ptr);
   free(ptr);
   return 0;
}

Närhelst realloc() i C resulterar i en misslyckad operation, returnerar den en nollpekare, och tidigare data frigörs också.

Dynamiska arrayer i C

En dynamisk array i C gör att antalet element kan växa efter behov. C Dynamic array används ofta i datavetenskapliga algoritmer.

I följande program har vi skapat och ändrat storleken på en dynamisk array i C

#include <stdio.h>
    int main() {
        int * arr_dynamic = NULL;
        int elements = 2, i;
        arr_dynamic = calloc(elements, sizeof(int)); //Array with 2 integer blocks
        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)); //reallocate 4 elements
        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);
    }

Resultat av C Dynamic array-programmet på skärmen:

 
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

Sammanfattning

  • Vi kan hantera minnet dynamiskt genom att skapa minnesblock efter behov i högen
  • I C Dynamic Memory Allocation allokeras minne vid en körningstid.
  • Dynamisk minnesallokering tillåter att manipulera strängar och arrayer vars storlek är flexibel och kan ändras när som helst i ditt program.
  • Det krävs när du inte har någon aning om hur mycket minne en viss struktur kommer att uppta.
  • Malloc() i C är en dynamisk minnesallokeringsfunktion som står för minnesallokering som block av minne med den specifika storleken initialiserad till ett skräpvärde
  • Calloc() i C är en sammanhängande minnesallokeringsfunktion som allokerar flera minnesblock åt gången initierad till 0
  • Realloc() i C används för att omallokera minne enligt den angivna storleken.
  • Funktionen Free() används för att rensa det dynamiskt allokerade minnet.