This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision | ||
dydaktyka:cprog:2015:dynamic_memory_allocation [2015/11/15 22:13] pkleczek [Przydzielanie pamięci – funkcja malloc] |
— (current) | ||
---|---|---|---|
Line 1: | Line 1: | ||
- | ====== Dynamiczna alokacja pamięci ====== | ||
- | W języku C można wyróżnić dwie podstawowe metody alokacji (przydzielania) pamięci: | ||
- | * **alokacja statyczna** -- ilość pamięci zostaje z góry określona na etapie pisania programu (poprzez odpowiednie deklaracje zmiennych); pamięć jest zwalniana automatycznie -- po zakończeniu bloku programu, w którym była deklarowana (chyba, że obiekt został zadeklarowany jako ''static''), lub po zakończeniu programu | ||
- | <code c> | ||
- | int a; | ||
- | char str[] = "Hello!"; | ||
- | float tab[5];</code> | ||
- | * **alokacja dynamiczna** -- program przydziela dowolne ilości pamięci w trakcie pracy, poprzez wywołanie odpowiednich funkcji; pamięć musi być jawnie zwolniona (z użyciem odpowiedniej funkcji) | ||
- | <code c> | ||
- | int* tab = (int*) malloc(5 * sizeof(int)); | ||
- | free(tab);</code> | ||
- | |||
- | Dynamiczna alokacja pamięci pozwala przede wszystkim na: | ||
- | * utworzenie tablicy o rozmiarze obliczanym dopiero podczas działania programu | ||
- | * dostęp do zmiennych utworzonych wewnątrz funkcji po wyjściu z nich | ||
- | |||
- | ===== Przydzielanie pamięci – funkcja "malloc" ===== | ||
- | |||
- | Funkcja [[http://www.cplusplus.com/reference/cstdlib/malloc/?kw=malloc|malloc()]] (od //memory allocation//) rezerwuje blok wolnej pamięci o zadanym rozmiarze (w bajtach) i zwraca adres jego pierwszego bajtu. W przypadku nieznalezienia wymaganego obszaru ''malloc()'' zwraca wskaźnik zerowy (dla przypomnienia -- wskaźnik o wartości ''0''). | ||
- | |||
- | Ponieważ rezerwowany blok może być zmienną dowolnego typu, funkcja ta zwraca uniwersalny "wskaźnik na ''void''". Choć można go przypisać bezpośrednio do wskaźnika pożądanego typu, do dobrego tonu należy zastosowanie w tym przypadku operatora rzutowania (poprawia to czytelność). | ||
- | |||
- | Aby utworzyć tablicę typu ''double'' o zadanym rozmiarze z użyciem funkcji ''malloc()'' można napisać następujący kod: | ||
- | <code c> | ||
- | int rozmiar = 10; | ||
- | double* tab = (double*) malloc(rozmiar * sizeof(double)); | ||
- | </code> | ||
- | |||
- | Powyższy kod zarezerwuje obszar pamięci dla 10 wartości typu ''double'' i przypisze adres wskaźnikowi ''tab''. Zauważ, że zmienna ''tab'' została zadeklarowana jako wskaźnik do pojedynczej wartości ''double'', a nie do bloku 10 takich wartości. Dlaczego? Ponieważ nazwa tablicy jest zarazem adresem jej pierwszego elementu, powyższe przypisanie umożliwia korzystanie z ''tab'' jak ze zwykłej nazwy tablicy (np. ''tab[0]'' to wartość jej pierwszego elementu). | ||
- | |||
- | ===== Zwalnianie pamięci – funkcja "free" ===== | ||
- | |||
- | Funkcja [[http://www.cplusplus.com/reference/cstdlib/free/?kw=free|free()]] zwalnia pamięć przydzieloną przez ''malloc()'' (i tylko taką). Argumentem funkcji ''free()'' jest adres obszaru pamięci do zwolnienia. | ||
- | |||
- | Na przykład: | ||
- | <code c> | ||
- | double* tab = (double*) malloc(8 * sizeof(double)); | ||
- | free(tab); | ||
- | </code> | ||
- | |||
- | :!: System operacyjny wyznacz limit pamięci, jaki może wykorzystać dany program -- jego przekroczenie powoduje "ubicie" programu. Zapominając zwolnić przydzieloną pamięć można łatwo doprowadzić do //[[https://pl.wikipedia.org/wiki/Wyciek_pami%C4%99ci|wycieku pamięci]]// i w konsekwencji właśnie do przedwczesnego zakończenia programu... |