Dynamická alokace paměti
Dynamická alokace paměti je v informatice označení pro rezervaci části operační paměti za běhu počítačového programu. Operační paměť spravuje v počítači část jádra nazývaná správce paměti (anglicky memory manager). Většina operačních systémů umožňuje paměť za běhu programu nejen alokovat (tj. proces nebo thread paměť od systému získá pro svoji potřebu), ale i vracet (proces vrací nepotřebnou paměť systému, aby mohla být později opět přidělena). U dynamické alokace nemusí být při překladu programu známá velikost potřebné části paměti pro ukládaná data (na rozdíl od statické alokace paměti).
Výhody a nevýhody
editovatStaticky alokovaná paměť je výhodná z hlediska rychlosti přístupu k uloženým datům. V určitých případech je ale nevýhodná z hlediska neefektivnosti manipulace s datovým prostorem. Představme si program, který setřídí zadané řetězce (slova, věty) podle abecedy. Není známo, kolik řetězců bude zadáno ani jejich velikost. Bylo by možné vytvořit pole o takovém počtu a velikosti položek, které s největší pravděpodobností nebude překročeno, například 500 položek o velikosti 128 bytů. Alokovaná paměť je statická, a proto se bude za běhu programu pracovat s celým polem, což zpomalí výpočet a zabere zbytečně mnoho paměťového prostoru. Možnosti, že bude potřeba setřídit 501 položek nebo že položka bude o něco větší, nejsou nijak ošetřeny.
Výhodou dynamicky alokované paměti je možnost kdykoliv uvolnit již zabraný paměťový prostor, což zvyšuje rychlost samotného programu i přes zvýšené datové nároky.
Vytváření dynamických proměnných v paměti je však časově náročnější než u statických, a proto může při neuváženém používání takových struktur docházet ke zpomalení celé aplikace.
Životní cyklus
editovatVýše zmíněné dva způsoby manipulace s paměťovým prostorem se liší mezi jinými i v délce existence. Zatímco paměť alokovaná staticky je uvolněna po přesně stanovené době, dynamicky alokovanou paměť musí uvolnit sám program nebo příslušný garbage collector. Dynamicky alokovaná paměť má tedy též dynamickou dobu existence.
Halda a ukazatel
editovatOznačení halda je ve svém původním významu (jak začalo být používáno v roce 1975) označení pro veškerou dostupnou paměť. Dnes je ale používáno k označení části paměti, která je využívána pro alokaci dynamické paměti (resp. dynamických proměnných). Protože předem není známo, kolik paměti bude potřeba, nemůže být datový prostor adresován přímo, nýbrž pomocí takzvaných ukazatelů (anglicky pointer). Ukazatele uchovávají adresu začátku alokované paměti: Například v případě pole ukazují na jeho první prvek, tedy na hodnotu s indexem nula.
Programovací jazyky a dynamická alokace paměti
editovatUkazatele v hojné míře využívají programátoři pracující v jazyce C, C++ a Pascalu. Ne všechny programovací jazyky umožňují používat ukazatele a nahrazují je referencemi na objekt (Python, Visual Basic .NET, Java apod.). Děje se tak proto, aby programátor nemohl pracovat přímo s adresami paměti a vyvaroval se tak zbytečných chyb.
Programovací jazyk C
editovatPro získání a uvolnění paměti jsou používány funkce malloc()
a free()
definovaných v hlavičkovém souboru standardní knihovny jazyka C (stdlib.h
):
void *malloc(size_t size);
Funkce malloc()
alokuje v paměti blok o velikosti size (v bytech) a její návratová hodnota je ukazatel na jeho začátek. Pokud funkce neproběhne v pořádku, například pokud není k dispozici požadovaná velikost paměti, vrací ukazatel null. Po alokaci obsahuje paměť náhodné hodnoty bitů, její obsah je nedefinovaný.
void free(void *ptr);
Funkce free()
uvolňuje prostor v paměti, který byl alokován funkcemi malloc()
, calloc()
nebo realloc()
. Jako argument je funkci předán ukazatel na začátek alokovaného bloku paměti. Takto uvolněná paměť je k dispozici pro další využití. Pokud nebudeme alokovanou paměť uvolňovat, může docházet k úniku paměti. Tento jev nastává, pokud dochází k opakovanému zabírání paměti, dokud nejsou vyčerpány všechny paměťové zdroje.
void *calloc(size_t num, size_t size);
Funkce calloc()
je alternativa funkce malloc()
s rozdílem, že calloc()
alokuje paměťový prostor pro num objektů, z nichž každý má velikost size. Takto alokovaná paměť ale neobsahuje náhodné hodnoty bitů, ale je vyplněna nulami. Z tohoto důvodu trvá alokace pomocí této funkce o něco déle.
void *realloc(void *ptr, size_t size);
Funkce realloc()
je určena pro změnu velikosti alokované paměti. Prvním argumentem je ukazatel na část paměti, která bude změněna a druhým argumentem je výsledná velikost rezervované paměti v bytech. Funkce opět vrací ukazatel na počátek datové struktury. Protože ale není zajištěno, že za již rezervovanou pamětí bude další prostor pro rozšíření, může nový ukazatel začátku odkazovat na úplně nové místo v paměti. Původní ukazatel *ptr již není možné užívat, ani od tohoto místa dealokovat paměť.