Dynamiczna alokacja pamięci w C przy użyciu funkcji malloc(), calloc().
Zanim nauczysz się alokacji pamięci dynamicznej C, zrozummy:
Jak działa zarządzanie pamięcią w C?
Kiedy deklarujesz zmienną przy użyciu podstawowego typu danych, kompilator C automatycznie przydziela miejsce w pamięci dla zmiennej w puli pamięci zwanej stos.
Na przykład zmienna zmiennoprzecinkowa po zadeklarowaniu zajmuje zwykle 4 bajty (w zależności od platformy). Możemy zweryfikować te informacje za pomocą rozmiar operator jak pokazano w poniższym przykładzie
#include <stdio.h> int main() { float x; printf("The size of float is %d bytes", sizeof(x)); return 0;}
Wyjście będzie:
The size of float is 4 bytes
Ponadto tablica o określonym rozmiarze jest alokowana w sąsiadujących blokach pamięci, każdy blok ma rozmiar jednego elementu:
#include <stdio.h> 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 się dowiedzieliśmy, przy deklarowaniu podstawowego typu danych lub tablicy, pamięć jest zarządzana automatycznie. Istnieje jednak proces alokacji pamięci w języku C, który umożliwia zaimplementowanie programu, w którym rozmiar tablicy jest niezdecydowany, dopóki program nie zostanie uruchomiony (w środowisku wykonawczym). Proces ten nazywa się „Dynamiczna alokacja pamięci".
Dynamiczna alokacja pamięci w C
Dynamiczne przydzielanie pamięci to ręczne przydzielanie i zwalnianie pamięci zgodnie z potrzebami programowymi. Pamięć dynamiczna jest zarządzana i obsługiwana za pomocą wskaźników wskazujących nowo przydzieloną przestrzeń pamięci w obszarze zwanym stertą.
Teraz możesz bez żadnych problemów dynamicznie tworzyć i niszczyć tablice elementów w czasie wykonywania. Podsumowując, automatyczne zarządzanie pamięcią wykorzystuje stos, a dynamiczna alokacja pamięci C wykorzystuje stertę.
The biblioteka posiada funkcje odpowiedzialne za dynamiczne zarządzanie pamięcią.
Funkcjonować | Cel |
---|---|
malloc () | Przydziela pamięć o żądanym rozmiarze i zwraca wskaźnik do pierwszego bajtu przydzieloną przestrzeń. |
kaloc() | 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 przydzielonej przestrzeni pamięci. |
Bezpłatny() | Zwalnia lub opróżnia wcześniej przydzieloną przestrzeń pamięci. |
Omówmy powyższe funkcje wraz z ich zastosowaniem
funkcja malloc() w C
Funkcja malloc() w języku C 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 wskaźnik zerowy wskazujący lokalizację pamięci. Zwracany 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 rzutu.
- Funkcja malloc() języka C zwraca wskaźnik do przydzielonej pamięci o rozmiarze bajtu.
Przykład malloc():
Example: ptr = (int *) malloc (50)
Po pomyślnym wykonaniu tej instrukcji rezerwowana jest pamięć o wielkości 50 bajtów. Adres pierwszego bajtu zarezerwowanej przestrzeni jest przypisany do wskaźnika ptr typu int.
Rozważ inny przykład:
#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)); } }
Wyjście:
Value of the 6th integer is 480
- Zauważ, że rozmiar(*ptr) użyto zamiast rozmiar(int) aby kod był bardziej odporny w przypadku późniejszej konwersji deklaracji *ptr na inny typ danych.
- Alokacja może się nie powieść, jeśli pamięć nie jest wystarczająca. W tym przypadku zwraca wskaźnik NULL. Powinieneś więc dołączyć kod sprawdzający wskaźnik NULL.
- 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 [ ]. Zalecamy używanie + do odwoływania się do elementów tablicy, ponieważ użycie inkrementacji ++ lub += zmienia adres przechowywany przez wskaźnik.
Funkcji Malloc() można używać również z typami danych znakowych oraz złożonymi typami danych, takimi jak struktury.
funkcja free() w C
Pamięć dla zmienne jest automatycznie zwalniany w czasie kompilacji. W przypadku dynamicznej alokacji pamięci należy jawnie zwolnić pamięć. Jeśli nie zostanie to zrobione, może wystąpić błąd braku pamięci.
Wolny() Funkcja ta jest wywoływana w celu zwolnienia/zwolnienia pamięci w języku C. Zwalniając pamięć w programie, udostępniasz ją do późniejszego wykorzystania.
Na przykład:
#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); }
Wyjście:
Value of the 2nd integer is 50
funkcja calloc() w C
Funkcja C calloc() oznacza ciągłe przydzielanie. Ta funkcja jest używana do przydzielania wielu bloków pamięci. Jest to dynamiczna funkcja przydzielania pamięci, która jest używana do przydzielania pamięci do złożonych struktur danych, takich jak tablice i struktury.
Funkcja Malloc() służy do alokacji pojedynczego bloku pamięci, podczas gdy funkcja calloc() w C służy do alokacji wielu bloków przestrzeni 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 alokacji n bloków pamięci o tym samym rozmiarze.
- Po przydzieleniu miejsca w pamięci wszystkie bajty są inicjowane na zero.
- 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 <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; }
Wynik:
Building and calculating the sequence sum of the first 10 terms Sum = 45
calloc() vs. malloc(): Kluczowe różnice
Poniżej przedstawiono kluczową różnicę między malloc() kontra calloc() w C:
Funkcja calloc() jest ogólnie bardziej odpowiednia i wydajna niż funkcja malloc(). Podczas gdy obie funkcje służą do przydzielania przestrzeni pamięci, calloc() może przydzielać wiele bloków jednocześnie. Nie musisz żądać bloku pamięci za każdym razem. Funkcja calloc() jest używana w złożonych strukturach danych, które wymagają większej przestrzeni pamięci.
Blok pamięci przydzielony przez funkcję calloc() w C jest zawsze inicjowany na zero, podczas gdy w funkcji malloc() w C zawsze zawiera wartość śmieciową.
funkcja realloc() w C
Korzystanie z C realloc() funkcji, możesz dodać więcej pamięci do już przydzielonej pamięci. Rozszerza bieżący blok, pozostawiając oryginalną treść bez zmian. realloc() w C oznacza realokację pamięci.
funkcji realloc() można także użyć do zmniejszenia 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 zostanie zwrócony 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 w nowym regionie. Daje pewność, że dane pozostaną bezpieczne.
Przykład 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; }
Za każdym razem, gdy realloc() w języku C kończy się niepowodzeniem operacji, zwraca wskaźnik null, a poprzednie dane również zostają zwolnione.
Tablice dynamiczne w C
Tablica dynamiczna w C pozwala na wzrost liczby elementów w razie potrzeby. Tablice dynamiczne C są szeroko stosowane w algorytmach informatyki.
W poniższym programie utworzyliśmy i zmieniliśmy rozmiar tablicy dynamicznej w 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); }
Wynik programu C Dynamic Array na ekranie:
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
Podsumowanie
- Możemy dynamicznie zarządzać pamięcią, tworząc bloki pamięci w razie potrzeby na stercie
- W C Dynamic Memory Allocation pamięć jest przydzielana w czasie wykonywania.
- Dynamiczna alokacja pamięci pozwala na manipulowanie ciągami 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 to dynamiczna funkcja alokacji pamięci, która oznacza alokację pamięci polegającą na tym, że bloki pamięci o określonym rozmiarze są inicjalizowane wartością śmieci
- Calloc() w C to ciągła funkcja alokacji pamięci, która przydziela wiele bloków pamięci w czasie inicjowanym na 0
- Realloc() w 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.