====== Dynamická pole ====== V této kapitole si představíme způsob, kterým můžeme pracovat s polem alokovaným až za běhu programu. ===== Alokace ===== Na následujícím příkladu si ukážeme, jak je to doopravdy s definicí (nebo deklarací) polí. unsigned char static[10]; unsigned char *dynamic; V obou případech vytvoříme pointer na char (případně pole), jediný rozdíl je v tom, že static je konstanta, kterou nelze měnit a obsahuje pointer na již alokované místo v paměti (to se alokovalo při definici), ale dynamic neobsahuje nic (resp. není inicializovaný) a nealokuje žádné místo (alokuje pouze místo pro sebe). Takže když chceme dynamic začít používat stejně jako static, stačí nám použít tento zápis: unsigned char static[10]; unsigned char *dynamic; //Deklarace pointeru na char (případně pole charů) dynamic = malloc(10); //Alokujeme 10 bytů a pointer na ně přiřadíme do pole if(!dynamic) { printf("Nelze alokovat paměť!\n"); exit(1); } Nyní můžeme k oběma polím přistupovat následujícím způsobem: static[3] = 'a'; dynamic[3] = 'a'; *(static + 3 * sizeof(char)) = 'a'; *(dynamic + 3 * sizeof(char)) = 'a'; Jak vidíte, k oběma polím (jak statickému tak dynamickému) můžeme přistupovat naprosto totožným způsobem, tedy pomocí operátoru [], který (jak jsme nyní zjistili) také zahrnuje dereferenci, nebo pomocí čistě dereferenčního operátoru a pointerové aritmetiky. ===== Pokročilé postupy ===== Pokud potřebujeme pole o proměnné velikosti, tak jediným možným způsobem zůstává vždy alokovat nové pole (o jiné velikosti) a stará data do něj v cyklu přetáhnout. Je samozřejmě vhodné staré pole uvolnit (pomocí free()). ===== Přetečení bufferu ===== Dobré je také vědět, že pokud načítáme jakákoli data od uživatele (např. z argumentů, klávesnice, sítě nebo souboru) a chceme je uložit do pole (např. řetězce), musíme pohlídat, aby data nepřetekla nad velikost pole, v takovém případě by mohlo dojít k pádu programu pokud by programu byl předán příliš dlouhý řetězec, nebo dokonce zápisu nebezpečného kódu na významná místa v paměti, pokud by se někdo pokusil program napadnout záměrně. Je tedy nutné si hlídat, jestli nepřekračujeme maximální offsety pole. ===== Samostatná cvičení ===== * Napište program, který dokáže do statického pole načíst z klávesnice libovolný řetězec tak, aby nebyla přesažena velikost pole. Nezapomeňte na to, že poslední znak pole musí být nulový. * Vytvořte obdobu předchozího programu, s tím, že se pole alokuje dynamicky. * Zkuste napsat program tak, aby zvládl načíst libovolně dlouhý řetězec do pole o proměnné velikosti.