Dynamiczne przydzielanie pamięci w C: funkcje malloc (), calloc ()

Spisie treści:

Anonim

Zanim nauczysz się alokacji pamięci dynamicznej C, zrozummy:

Jak działa zarządzanie pamięcią w C?

Gdy deklarujesz zmienną przy użyciu podstawowego typu danych, kompilator C automatycznie przydziela miejsce w pamięci dla zmiennej w puli pamięci zwanej stosem .

Na przykład zmienna zmiennoprzecinkowa zajmuje zwykle 4 bajty (w zależności od platformy), gdy jest zadeklarowana. Możemy zweryfikować te informacje za pomocą operatora sizeof , jak pokazano na poniższym przykładzie

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

Wynik będzie:

 The size of float is 4 bytes 

Ponadto tablica o określonym rozmiarze jest alokowana w ciągłych blokach pamięci, każdy blok ma rozmiar dla jednego elementu:

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

Wynik to:

 The size of the float array with 10 element is 40

Jak dotychczas dowiedzieliśmy się, przy deklarowaniu podstawowego typu danych lub tablicy pamięć jest zarządzana automatycznie. Istnieje jednak proces przydzielania pamięci w C, który pozwoli ci zaimplementować program, w którym rozmiar tablicy jest niezdecydowany, dopóki nie uruchomisz programu (środowisko wykonawcze). Ten proces nazywa się „ dynamiczną alokacją pamięci ”.

W tym samouczku nauczysz się:

  • Jak działa zarządzanie pamięcią w C?
  • Dynamiczne przydzielanie pamięci w C
  • Funkcja C malloc ()
  • Funkcja free ()
  • Funkcja calloc () języka C.
  • calloc () vs. malloc (): kluczowe różnice
  • Funkcja C realloc ()
  • Tablice dynamiczne

Dynamiczne przydzielanie pamięci w C

Dynamiczne przydzielanie pamięci to ręczne przydzielanie i zwalnianie pamięci zgodnie z potrzebami programistycznymi. Pamięć dynamiczna jest zarządzana i obsługiwana za pomocą wskaźników wskazujących na nowo przydzieloną przestrzeń pamięci w obszarze, który nazywamy stertą.

Teraz możesz bezproblemowo tworzyć i niszczyć tablicę elementów dynamicznie w czasie wykonywania. Podsumowując, automatyczne zarządzanie pamięcią używa stosu, a dynamiczna alokacja pamięci C korzysta ze sterty.

Biblioteka zawiera funkcje odpowiedzialne za dynamiczne zarządzanie pamięcią.

Funkcjonować Cel, powód
malloc () Przydziela pamięć o żądanym rozmiarze i zwraca wskaźnik do pierwszego bajtu przydzielonego miejsca.
calloc () Przydziela miejsce na elementy tablicy. Inicjuje elementy do zera i zwraca wskaźnik do pamięci.
realloc () Służy do modyfikowania rozmiaru wcześniej przydzielonego miejsca w pamięci.
Darmowy() Zwalnia lub opróżnia wcześniej przydzieloną przestrzeń pamięci.

Omówmy powyższe funkcje z ich zastosowaniem

Funkcja C malloc ()

Funkcja C malloc () oznacza alokację pamięci. Jest to funkcja służąca do dynamicznego przydzielania bloku pamięci. Rezerwuje przestrzeń pamięci o określonym rozmiarze i zwraca pusty wskaźnik wskazujący na lokalizację pamięci. Zwrócony wskaźnik jest zwykle typu void. Oznacza to, że możemy przypisać funkcję C malloc () do dowolnego wskaźnika.

Składnia funkcji malloc ():

ptr = (cast_type *) malloc (byte_size);

Tutaj,

  • ptr jest wskaźnikiem typu cast_type.
  • Funkcja C malloc () zwraca wskaźnik do przydzielonej pamięci o rozmiarze byte_size.

Przykład malloc ():

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

Po pomyślnym wykonaniu tej instrukcji zarezerwowana zostaje przestrzeń pamięci o wielkości 50 bajtów. Adres pierwszego bajtu zarezerwowanej przestrzeni jest przypisany do wskaźnika ptr typu int.

Rozważ inny przykład:

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

Wynik:

Value of the 6th integer is 480

  1. Zwróć uwagę, że zamiast sizeof (int) użyto sizeof (* ptr) , aby kod był bardziej niezawodny, gdy deklaracja * ptr zostanie później wpisana na inny typ danych.
  2. Alokacja może się nie powieść, jeśli pamięć nie jest wystarczająca. W tym przypadku zwraca wskaźnik NULL. Dlatego należy dołączyć kod sprawdzający wskaźnik NULL.
  3. Należy pamiętać, że przydzielona pamięć jest ciągła i może być traktowana jako tablica. Możemy użyć arytmetyki wskaźników, aby uzyskać dostęp do elementów tablicy, zamiast używać nawiasów kwadratowych []. Radzimy używać + do odwoływania się do elementów tablicy, ponieważ użycie inkrementacji ++ lub + = zmienia adres przechowywany przez wskaźnik.

Funkcji Malloc () można również używać z typem danych znakowych, a także ze złożonymi typami danych, takimi jak struktury.

Funkcja free ()

Pamięć dla zmiennych jest automatycznie zwalniana w czasie kompilacji. W dynamicznej alokacji pamięci musisz jawnie zwolnić pamięć. Jeśli tego nie zrobisz, możesz napotkać błąd braku pamięci.

Funkcja free () jest wywoływana w celu zwolnienia / zwolnienia pamięci w C. Zwalniając pamięć w programie, udostępniasz jej więcej do późniejszego użytku.

Na przykład:

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

Wynik

 Value of the 2nd integer is 50

Funkcja calloc () języka C.

Funkcja calloc () w języku C oznacza ciągłą alokację. Ta funkcja służy do przydzielania wielu bloków pamięci. Jest to funkcja dynamicznego przydzielania pamięci, która służy do przydzielania pamięci do złożonych struktur danych, takich jak tablice i struktury.

Funkcja Malloc () służy do przydzielania pojedynczego bloku pamięci, podczas gdy calloc () w C służy do przydzielania wielu bloków pamięci. Każdy blok przydzielony przez funkcję calloc () ma ten sam rozmiar.

Składnia funkcji calloc ():

ptr = (cast_type *) calloc (n, size);
  • Powyższa instrukcja służy do przydzielenia n bloków pamięci o tym samym rozmiarze.
  • Po przydzieleniu miejsca w pamięci wszystkie bajty są inicjowane do zera.
  • Zwracany jest wskaźnik, który aktualnie znajduje się na pierwszym bajcie przydzielonej przestrzeni pamięci.

Ilekroć wystąpi błąd przy przydzielaniu miejsca w pamięci, taki jak brak pamięci, zwracany jest wskaźnik zerowy.

Przykład calloc ():

Poniższy program oblicza sumę ciągu arytmetycznego.

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

Wynik:

Building and calculating the sequence sum of the first 10 termsSum = 45

calloc () vs. malloc (): kluczowe różnice

Poniżej znajduje się kluczowa różnica między malloc () a calloc () w C:

Funkcja calloc () jest ogólnie bardziej odpowiednia i wydajniejsza niż funkcja malloc (). Podczas gdy obie funkcje są używane do przydzielania miejsca w pamięci, calloc () może przydzielać wiele bloków jednocześnie. Nie musisz za każdym razem prosić o blok pamięci. Funkcja calloc () jest używana w złożonych strukturach danych, które wymagają większej przestrzeni pamięci.

Blok pamięci przydzielony przez calloc () w C jest zawsze inicjalizowany do zera, podczas gdy w funkcji malloc () w C zawsze zawiera wartość śmieci.

Funkcja C realloc ()

Używając funkcji C realloc () , możesz zwiększyć rozmiar pamięci do już przydzielonej pamięci. Rozszerza bieżący blok, pozostawiając oryginalną zawartość bez zmian. realloc () w C oznacza realokację pamięci.

Funkcja realloc () może również służyć do zmniejszania rozmiaru wcześniej przydzielonej pamięci.

Składnia funkcji realloc ():

ptr = realloc (ptr,newsize);

Powyższa instrukcja przydziela nową przestrzeń pamięci o określonym rozmiarze w zmiennej newsize. Po wykonaniu funkcji wskaźnik wróci do pierwszego bajtu bloku pamięci. Nowy rozmiar może być większy lub mniejszy niż poprzednia pamięć. Nie możemy być pewni, czy nowo przydzielony blok będzie wskazywał tę samą lokalizację, co poprzedni blok pamięci. Ta funkcja skopiuje wszystkie poprzednie dane z nowego regionu. Daje pewność, że dane pozostaną bezpieczne.

Przykład realloc ():

#include 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 sizestrcat(ptr, " In 'C'");printf(" %s, Address = %u\n", ptr, ptr);free(ptr);return 0;} 

Za każdym razem, gdy realloc () w C powoduje nieudaną operację, zwraca wskaźnik zerowy, a poprzednie dane również są zwalniane.

Tablice dynamiczne w C

Tablica dynamiczna w języku C pozwala na zwiększenie liczby elementów w razie potrzeby. Tablice dynamiczne C są szeroko stosowane w algorytmach informatycznych.

W poniższym programie utworzyliśmy tablicę dynamiczną i zmieniliśmy jej rozmiar w języku C

#include int main() {int * arr_dynamic = NULL;int elements = 2, i;arr_dynamic = calloc(elements, sizeof(int)); //Array with 2 integer blocksfor (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 elementsprintf("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);} 

Wynik programu C Dynamic array na ekranie:

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

Podsumowanie

  • Możemy dynamicznie zarządzać pamięcią, tworząc w razie potrzeby bloki pamięci w stercie
  • W C Dynamic Memory Allocation pamięć jest przydzielana w czasie wykonywania.
  • Dynamiczna alokacja pamięci umożliwia manipulowanie łańcuchami i tablicami, których rozmiar jest elastyczny i można go zmienić w dowolnym momencie w programie.
  • Jest to wymagane, gdy nie masz pojęcia, ile pamięci zajmie dana struktura.
  • Malloc () w C jest funkcją dynamicznej alokacji pamięci, która oznacza alokację pamięci, która blokuje pamięć o określonym rozmiarze zainicjowaną jako wartość bezużyteczna
  • Calloc () w C jest ciągłą funkcją alokacji pamięci, która przydziela wiele bloków pamięci na raz zainicjowany na 0
  • Realloc () w języku C służy do ponownego przydzielania pamięci zgodnie z określonym rozmiarem.
  • Funkcja Free () służy do czyszczenia dynamicznie przydzielanej pamięci.