9. DYNAMICKÉ DÁTOVÉ ŠTRUKTÚRY

Podobné dokumenty
Programovanie v jazyku C - to chce dynamiku

Programovanie v jazyku C - pole treba poorat...

IUJCE 07/08 Přednáška č. 6

Úroveň strojového kódu procesor Intel Pentium. Adresovanie pamäte

MANUÁL K TVORBE CVIČENÍ NA ÚLOHY S POROZUMENÍM

PODPROGRAMY. Vyčlenenie podprogramu a jeho pomenovanie robíme v deklarácii programu a aktiváciu vykonáme volaním podprogramu.

8. Relácia usporiadania

ALGORITMY A PROGRAMOVANIE VO VÝVOJOVOM PROSTREDÍ LAZARUS. Vývojové prostredie Lazarus, prvý program

Čo ak program potrebuje pamäť, ktorej veľkosť závisí od konkrétneho vstupu?

Školská sieť EDU. Rozdelenie škôl. Obsah: Deleba škôl podľa času zaradenia do projektu: Delba škôl podľa rýchlosti pripojenia:

Vytvorenie používateľov a nastavenie prístupov

Strojový kód, assembler, emulátor počítača

Operačný systém Úvodná prednáška

Prevody z pointfree tvaru na pointwise tvar

Hromadná korešpondencia v programe Word Lektor: Ing. Jaroslav Mišovych

Polia a matice v jazyku C. Michal Kvasnica

Funkcia - priradenie (predpis), ktoré každému prvku z množiny D priraďuje práve jeden prvok množiny H.

Programovanie I. Úvod do programovania Mgr. Stanislav Horal, Katedra informatiky, FPV, UCM

Príklad ponuky: Riešenie: vrch. hodnota 3 hodnota 2 hodnota 1

Program "Inventúra program.xlsm"

Návod k servisnému programu pre fiskálny modul FM2000. manuál. (c)varos

Mgr. Stanislav Fila, psychológ CPPPaP Banská Bystrica Centrum pedagogicko-psychologického poradenstva a prevencie (bývalá KPPP) Banská Bystrica

Import Excel Univerzál

Mgr. Stanislav Fila, psychológ CPPPaP Banská Bystrica Centrum pedagogicko-psychologického poradenstva a prevencie (bývalá KPPP) Banská Bystrica

Ako započítať daňovú licenciu

P R O L U C. POZNÁMKY individuálnej účtovnej závierky pre rok 2014

Pracovné prostredie MS EXCEL 2003.

Programovanie v jazyku C - struktury a polia

Objektovo orientované programovanie v C# ERIK KUČERA METÓDY VÝPOČTOVEJ INTELIGENCIE PREDNÁŠKA 3

Operační systémy. Cvičení 4: Programování v C pod Unixem

Dynamická alokácia pamäte a smerníky

VYSPORIADANIE PREHRADENÝCH ZÁVÄZKOV A POHĽADÁVOK

Import cenových akcií FRESH

Používateľská príručka pre autorov

7.1 Návrhové zobrazenie dotazu

M úlohy (vyriešené) pre rok 2017

VECIT 2006 Tento materiál vznikol v rámci projektu, ktorý je spolufinancovaný Európskou úniou. 1/4

Manuál pripojenia sa k IP zariadeniu HikVision (videorekordéra, IP kamery, videoservera..) pomocou DDNS servera HikVision.

Imagine. Popis prostredia:

Užívateľská príručka systému CEHZ. Základné zostavy Farmy podľa druhu činnosti

KOMISNÝ PREDAJ. Obr. 1

Total Commander. Základné nastavenia

PLASTOVÉ KARTY ZÁKAZNÍKOV

KEO - Register obyvateľov Prevod údajov

Návod na inštaláciu sieťovej tlačiarne KONICA MINOLTA C20P pre Windows XP a Vista

Microsoft Outlook. Stručný prehľad základných funkcií. Ing.Anna Grejtáková, SPP DFBERG

Používateľská príručka pre autorov Prihlásenie

1. Formát exportov typu *.gpc (ABO)

Kombinatorická pravdepodobnosť (opakovanie)

Vysoké školy na Slovensku Prieskum verejnej mienky

Program ovocie a zelenina do škôl Školské ovocie

Studentove t-testy. Metódy riešenia matematických úloh

Kombinatorická pravdepodobnosť (opakovanie)

tipov pre kvalitnú tlač Na jednoduchých príkladoch Vám ukážeme ako postupovať a na čo si dávať pozor pri príprave podkladov na kvalitnú tlač.

Jednoduchá správa pamäte

Textový editor WORD. Práca s obrázkami a automatickými tvarmi vo Worde

Úvod do jazyka C. Ing. Jan Fikejz (KST, FEI) Fakulta elektrotechniky a informatiky Katedra softwarových technologií

MATLAB (1) - úvod do programovania vedeckých problémov. LS 2017, 8.predn.

Moderné vzdelávanie pre vedomostnú spoločnosť/projekt je spolufinancovaný zo zdrojov EÚ. Grafy

Spracovanie informácií

F akulta B aníctva, E kológie, R iadenia a G eotechnológií. Mozilla Firefox. Ing. Anna Grejtáková SPP D FBERG 2011

DVDStyler. Získanie programu. Inštalovanie. Začíname tvoriť DVD

Zápis predmetov do AiSu na aktuálny akademický rok

Postup pri aktivácii elektronickej schránky na doručovanie pre právnické osoby, ktoré nie sú zapísané do obchodného registra

IUJCE Přednáška č. 11. další prvky globální proměnné, řízení viditelnosti proměnných, funkcí

Blokové a prúdové šifry

CVIČENIE 1 : ZÁKLADNÉ VÝPOČTY PRAVDEPODOBNOSTI

Zálohy (príjem, odpočítanie) bez modulu Sklad - Prijaté zálohy

DÁTOVÉ PRVKY NA POPIS ČÍSELNÍKA

Metodické usmernenie č. 4/2007 k poskytovaniu informácií prostredníctvom portálu Úradu pre dohľad nad zdravotnou starostlivosťou

Automatický timer pre DX7 návod na inštaláciu a manuál

Postup pri aktivácii elektronickej schránky na doručovanie pre fyzické osoby

3 Determinanty. 3.1 Determinaty druhého stupňa a sústavy lineárnych rovníc

Vážení používatelia programu WISP.

Postup registrácie certifikátov do Windows

Virtuálna Registračná Pokladnica. Modul OPD pre ios

Čo je to Refactoring?

Dealer Extranet 3. Cenové ponuky

AIS2 Hodnotenie študentov po skúške POMÔCKA PRE VYUČUJÚCICH

Konfigurácia IP Bell 02C Dverný vrátnik a FIBARO Home Center 2

Informatika a jej jednotlivé oblastí

Starogrécky filozof Demokritos ( pred n.l) Látky sú zložené z veľmi malých, ďalej nerozdeliteľných častíc - atómov

nastavenie a realizácia vzájomných zápočtov v Money S4 / Money S5

Príručka Mobility Tool + pre príjemcov grantu

SLOVENSKÁ TECHNICKÁ UNIVERZITA V BRATISLAVE FAKULTA INFORMATIKY A INFORMAČNÝCH TECHNOLÓGIÍ. Metodika verzií zdrojového kódu

DOBROPISY. Dobropisy je potrebné rozlišovať podľa základného rozlíšenia: 1. dodavateľské 2. odberateľské

Formuláre PowerPoint MGR. LUCIA BUDINSKÁ,

Skupiny finančných nástrojov a produktov zodpovedajúce typu investora

Návod na vkladanie záverečných prác do AIS

INŠTALAČNÝ MANUÁL. TMEgadget

NEVLASTNÁ VODIVOSŤ POLOVODIČOVÉHO MATERIÁLU TYPU P

Skákalka. Otvoríme si program Zoner Callisto, cesta je Programy Aplikácie Grafika Zoner Callisto.

Základy algoritmizácie a programovania

Vybrané novinky v IS WISP

OCHRANA INOVÁCIÍ PROSTREDNÍCTVOM OBCHODNÝCH TAJOMSTIEV A PATENTOV: DETERMINANTY PRE FIRMY EURÓPSKEJ ÚNIE ZHRNUTIE

Návod na používanie súboru na vyhodnotenie testov všeobecnej pohybovej výkonnosti

Algoritmizace a programování

1. Gigabajty si hneď v prvom kroku premeníme na gigabity a postupne premieňame na bity.

Manuál Generovanie prístupových práv E-Recept

Př. další použití pointerů

Transkript:

9. DYNAMICKÉ DÁTOVÉ ŠTRUKTÚRY 9.1. Dynamická alokácia pamäte. 9.2. Zoznam. 9.3. Pole ukazovateľov. Dynamické dátové štruktúry predstavujú akýsi protiklad ku statickým dátovým štruktúram. Povedzme si teda najprv niečo o nich. Porovnaním ich vlastností lepšie vyniknú prednosti tých či oných pre isté triedy úloh. Statické dáta (SD) majú svoju veľkosť presne a nemenne určenú v okamihu prekladu zdrojového textu. Preto sa s nimi pracuje jednoduchšie. Odpadá možnosť práce s nepridelenou pamäťou. Potiaľ klady. Teraz zápory. Nech náš program potrebuje viac či menej dát, nedá sa s tým nič robiť. Preto často radšej volíme SD trochu naddimenzované, aby náš program zvládol "väčšinu" úloh, ktorých triedu je schopný riešiť. Pre príklady nemusíme chodiť ďaleko. Ak napíšeme program pre prácu s maticami postavený na SD, musíme určiť ich dimenziu. Dimenzia 3 x 3 asi nepostačí, tak radšej siahneme k dimenzii 10 x 10, alebo radšej k 20 x 20. A budeme mať dobrý pocit, že naša úloha vyrieši všetko. Pocit je pochopiteľne mylný. Úloha si neporadí už s maticou 21 x 21. Naviac kladieme na OS vždy rovnaké, a to väčšinou premrštené, požiadavky na operačnú pamäť. V jednoúlohovom systéme to obvykle nevadí. Vo viacúlohovom, nieto ešte viacuživateľskom prostredí je takéto plytvanie takmer neodpustiteľné. SD sú pochopiteľne statické v zmysle veľkosti pamäte, ktorú majú pridelenú. Ich hodnoty sa behom programu môžu meniť. Dynamické dáta (DD) nemajú veľkosť pri preklade určenú. Pri preklade sú vytvorené iba premenné vhodného typu ukazovateľ na, ktoré nám za chodu slúžia ako pevné body pre prácu s DD. O požadovaný pamäťový priestor však musíme požiadať OS. Ten našu žiadosť uspokojí, alebo nie. Rozhodne však žiadame vždy len toľko pamäte, koľko sa za chodu ukázalo byť potrebné. Popravde povedané, požadujeme jej trošku viac. Ta trocha naviac je daná jednak nutnou réžiou, jednak našimi schopnosťami. Záleží len na nás, ako vhodné dynamické dátové štruktúry vyberieme (alebo si obľúbime). Pochopiteľne vznikajú mnohé nebezpečia, najmä pri zabudnutí požiadania o pamäť a zápise do nepridelených priestorov. DD majú ešte jednu prednosť oproti SD. Pokiaľ požiadavky na DD vystupujú v na sebe nezávislých častiach programu, môže pamäťová oblasť byť menšia, než prostý súčet týchto požiadavkou. Akonáhle totiž končí časť programu, vráti pridelenú časť DD späť. Naopak nový úsek programu podľa potreby o pamäť požiada. DD teda znižujú pamäťové nároky z dvoch dôvodov. Jednak preto, že požadujú toľko pamäte, koľko je potrebné. Jednak vďaka možnému viacnásobnému používaniu pridelenej dynamickej pamäti. SD sú umiestnené v dátovom segmente. Klasický program je totiž rozdelený na dátový segment a kódový segment. Kódový segment obsahuje kód, ktorý prekladač vytvorí na základe nášho zdrojového textu. Tento kód by sa za chodu programu teda nemal meniť. Nemennosť kódového segmentu

operačné systémy obvykle kontrolujú a zaručujú. MS-DOS však nie. Práve z toho plynú prakticky isté havárie dokonca celého OS pri chybnej práci s ukazovateľmi. Dátový segment je opäť vytvorený prekladačom. Sú v ňom umiestnené všetky statické dáta programu. Táto časť programu sa behom chodu programu mení. Okrem kódového a dátového segmentu prideľuje pri spustení programu OS ešte isté prostredie. To má buď nejakú štandardnú veľkosť, alebo je táto veľkosť určená na základe požiadavkou zavádzaného programu. Tu je umiestnený zásobník. O ňom vieme, že je potrebný pri predávaní argumentov funkciám, návratové hodnoty od funkcií a tiež pre nájdenie návratovej adresy po ukončení funkcie. Táto návratová adresa je do zásobníka zapísaná pri volaní funkcie. Zásobník však spravidla neobsadí celú zostatkovú pamäť, ktorú má program (proces) k dispozícii. Časť pridelenej pamäte zostáva voľná. Tej sa spravidla hovorí hromada či halda (heap). Jej veľkosť môžeme pri tvorbe programu určiť. A práve halda predstavuje oblasť pamäte, do ktorej sa umiestňujú DD. 9.1. Dynamická alokácia pamäte. Aby časti programu mohli ako žiadať o pridelenie dynamickej pamäte, tak už nepotrebnú pamäť vracať, musí existovať aspoň základná programová podpora. Tu si však nebudeme vytvárať sami. Je definovaná ANSI normou jazyka a teda ju dostávame spolu s prekladačom. Súhrne sa programová podpora pre dynamickú alokáciu pamäte nazýva podľa oblasti, ktorej sa prideľovanie týka, správca haldy (heap manager). Súčasťou správcu haldy sú nielen potrebné funkcie, ale aj dátové štruktúry. Ako užívateľa nás pochopiteľne zaujímajú predovšetkým funkcie správcu haldy. Popíšme si teda niektoré z nich. Náš výber je určený predovšetkým ich prenositeľnosťou. Deklarácie funkcií správcu haldy sú umiestnené v alloc.h, prípadne v stdlib.h. void *malloc(size_t size); predstavuje požiadavku o pridelenie súvislého bloku pamäte o veľkosti size. Ak je úspešný, dostávame ukazovateľ na jeho začiatok, inak NULL. void *calloc(size_t nitems, size_t size); ako predchádzajúca s tým, že naša požiadavka je rozložená na nitems položiek, každá o size bytoch. Naviac je pridelená pamäť vyplnená nulami. void free(void *block); je naopak vrátenie skôr alokovanej pamäte, na ktorú ukazuje block. void *realloc(void *block, size_t size); umožňuje zmeniť veľkosť alokovanej pamäte, na ktorú ukazuje block na novú veľkosť určenú hodnotou size. V prípade potreby (požiadavka je väčšia, než pôvodný blok) je obsah pôvodného bloku prekopírovaný. Vracia ukazovateľ na nový blok.

UNIX a MS-DOS definujú pre dynamickú zmenu veľkosti haldy dvojicu funkcií. Prvá z nich, int brk(void *addr); nastaví hranicu haldy programu na hodnotu danú addr. Druhá z dvojice, void *sbrk(int incr); umožní zvýšiť túto hodnotu o incr bajtov. MS-DOS pridáva ešte funkciu, ktorá vracia počet voľných bajtov na hromade (v závislosti na pamäťovom modely vracia unsigned int alebo unsigned long): unsigned coreleft(void); Krátku ukážku pridelenia a vrátenia pamäte pre reťazec predstavujú dve nasledujúce funkcie. Rozsiahlejšie a úplné programy sú súčasťou každej z nasledujúcich podkapitol. char *newstr(char *p) register char *t; t = malloc(strlen(p) + 1); strcpy(t, p); return t; void freestr(char *p) free(p); Prvá funkcia vytvorí na hromade dostatočný priestor a nakopíruje doň predávaný reťazec. Ukazovateľ na túto kópiu vracia ako svoju funkčnú hodnotu. Druhá funkcia prevádza činnosť opačnú. Oblasť určenú ukazovateľom vráti správcovi haldy. Detailné vlastnosti správcu haldy môžu byť rôzne. Čomu sa však obvykle nevyhneme je situácia nazvaná segmentácia haldy. Ak nie sú úseky z haldy vrátené v opačnom poradí, než boli prideľované (LIFO), vzniknú na hromade striedavo úseky voľnej a obsadenej pamäte. Celková veľkosť volnej pamäte, daná súčtom všetkých voľných úsekov, je potom väčšia než veľkosť najväčšieho súvislého voľného bloku. Môže potom nastať situácia, kedy voľnej pamäte je síce dosť, ale naša požiadavka na jej pridelenie nie je uspokojená, pretože nie je k dispozícii dostatočne veľká súvislá oblasť. 9.2. Zoznam. Je dynamická dátová štruktúra, ktorá medzi svojimi členmi obsahuje okrem dátovej časti aj väzobný člen, ktorý ukazuje na nasledujúci prvok zoznamu, alebo NULL, ak je posledným prvkom. Dátové minimum, ktoré pre správu zoznamu potrebujeme, je ukazovateľ na jeho prvý prvok. Popísaný zoznam sa rovnako nazýva jednosmerný. Postupne totiž môžeme prejsť od začiatku zoznamu až na jeho koniec, nie však naopak. Existuje ešte jeden variant zoznamu, majúci väzobné členy dva. Jeden ukazuje opäť na následníka, druhý na predchodcu.

Ukážku použitia zoznamu prináša nasledujúca úloha (a program). Majme za úlohu spočítať početnosť výskytu všetkých slov vo vstupnom texte. Pre jednoduchosť budeme rozlišovať malé a veľké písmena. Na záver vytlačíme tabuľku, v ktorej bude uvedená početnosť výskytu a reťazec, predstavujúci slovo. Za slová považuje program reťazce písmen a číslic. Túto skutočnosť však môžeme meniť úpravou vlastností funkcie odstran_neslova. Mená funkcií aj premenných v programe sú volené s ohľadom na ich maximálnu popisnosť. Vstupom môže byť súbor, ak je zadaný ako 1. argument príkazového riadku. Inak je vstupom štandardný vstup. Jednosmerný zoznam Obrázok odpovedá dátovej štruktúre vytvorenej v programe. Hodnoty sú iba ilustratívne. Jediný nedynamický objekt zoznamu je ukazovateľ prvy na začiatok zoznamu. Ostatné objekty sú dynamické. V obrázku je táto skutočnosť odlíšená tvarom rohov obdĺžnikov. Obrázok môže byť aj návodom, ako dynamické objekty rušiť. Táto činnosť totiž v programe nie je obsiahnutá. Rozhodne je zrejmé, že musíme uvolniť ako pamäť vyčlenenú pre hodnoty typu struct_info, tak aj pamäť, ktorú obsadzujú reťazce, na ktoré je zo štruktúry ukazované. /****************************************************************/ /* subor SLOVA.C */ /* prevedie nacitanie vstupneho textu, jeho rozlozenie na slova */ /* a z tychto slov vytvori zoznam s ich pocetnostou vyskytu. */ /* Na zaver vytlaci slova a ich pocetnost. */ /****************************************************************/ #include <stdio.h> #include <string.h> #include <alloc.h> #include <ctype.h> #include <conio.h> #define DLZKA_RIADKU 500 #define PAGE 24 /* typedef struct info; */ typedef struct struct_info int pocet; char *slovo; struct struct_info *dalsi; info; void odstran_neslova(char *ptr) /* odstrani medzery, tabelatory a znaky CR, LF zo zaciatku retazca */ char *pom; pom = ptr;

if (strlen(ptr) == 0) return; while ((*pom!= '\0') && ((*pom == 0x20) (*pom == '\t') (*pom == '\n') (*pom == '\r') (!isalnum(*pom)))) pom++; strcpy(ptr, pom); /* void odstran_neslova(char *ptr) */ void vrat_slovo(char *r, char *s) int i = 0; while ((r[i]!= 0x0) && (isalnum(r[i]) (r[i] == '_'))) i++; /* while */ if (i == 0) *s = 0x0; else strncpy(s, r, i); s[i] = 0x0; strcpy(r, r + i); /* void vrat_slovo(char *r, char *s) */ void pridaj_slovo(info **prvy, char *s) info *prvok; prvok = *prvy; while (prvok!= NULL) if (strcmp(s, prvok->slovo) == 0) (prvok->pocet)++; return; prvok = prvok->dalsi; prvok = malloc(sizeof(info)); prvok->slovo = malloc(strlen(s) + 1); strcpy(prvok->slovo, s); prvok->pocet = 1; prvok->dalsi = *prvy; *prvy = prvok; /* void pridaj_slovo(info **prvy, char *s) */ void vytlac(info *prvy) int vytlacene = 0; while (prvy!= NULL) printf("%4d..%s\n", prvy->pocet, prvy->slovo); prvy = prvy->dalsi; vytlacene ++; if ((vytlacene % PAGE) == 0) printf("pre pokracovanie stlac klavesu"); getch(); printf("\n"); /* void vytlac(info *prvy) */ int main(int argc, char **argv)

info *prvy = NULL; char riadok[dlzka_riadku + 1], slovo[dlzka_riadku + 1]; FILE *f; if (argc!= 1) f = fopen(argv[1], "rt"); else f = stdin; if (f == NULL) return(1); while (fgets(riadok, DLZKA_RIADKU, f)!= NULL) odstran_neslova(riadok); while (strlen(riadok)!= 0) vrat_slovo(riadok, slovo); odstran_neslova(riadok); pridaj_slovo(&prvy, slovo); vytlac(prvy); return 0; /* int main(int argc, char **argv) */ 9.3. Pole ukazovateľov. Veľmi pohodlnou dynamickou dátovou štruktúrou je dynamické pole ukazovateľov. Princíp je jednoduchý. Požiadame o pamäť pre dostatočne veľké pole ukazovateľov. Ďalej už pracujeme rovnako, ako by pole bolo statické (až na ten ukazovateľ na pole naviac). K jednotlivým prvkom môžeme pristupovať pomocou indexu. Nesmieme zabudnúť, že prvky sú ukazovatele, a že teda musíme pamäť, na ktorú ukazujú, tiež alokovať. Vďaka funkcii realloc() máme možnosť ľahko meniť počet prvkov nášho poľa ukazovateľov. Naviac s tým, že naše dynamické dáta svoju adresu nemenia a funkcia realloc() prenesie správne (stále platné) adresy do nového (väčšieho) bloku ukazovateľov. My k nim pristupujeme pomocou rovnakej premennej, indexy všetkých prvkov zostavajú rovnaké, len ich pribudlo. Skvelé. Ukážková úloha, ktorú riešime, načíta vstupné riadky textu, ukladá ich na hromadu s prístupom pomocou poľa ukazovateľov a nakoniec riadku vytlačí v rovnakom poradí, v akom boli načítané. Hodnoty START a PRIRASTOK sú úmyselne volené malé, aby sa ukázala možnosť realokácie poľa aj pri zadávaní vstupu z klávesnice. Pre rozsiahlejšie pokusy doporučujeme presmerovať vstup. /************************************************/ /* subor STR_ARRY.C */ /* zo standardneho vstupu cita riadky, alokuje */ /* pre ne pamat a ukazovatele na tuto kopiu */ /* nacitaneho riadku uklada do pola ukazovatelov */ /* pole ukazovatelov ma pociatocnu velkost, ktora */ /* sa vsak v pripade potreby zmeni - realloc() */ /* po ukonceni vstupu nacitane riadky vytlaci */ /************************************************/ /********************************/ /* obvykle navratove hodnoty: */ /* O.K. 0 */ /* error!0 (casto -1)*/

/********************************/ #include <stdio.h> #include <alloc.h> #include <string.h> #define LADENIE #define START 2 #define PRIRASTOK 1 #define DLZKA_RIADKU 100 typedef char * typedef retazec * retazec; pole_retazcov; #if defined(ladenie) void volno(void) printf("\nje volnych %10lu bajtov\n", coreleft()); /* LARGE */ /* void volno(void) */ void uvolni(pole_retazcov *p_r, int pocet) int i; for (i = 0; i < pocet; i++) free((*p_r)[i]); free(*p_r); /* void uvolni(pole_retazcov *p_r, int pocet) */ #endif /* defined(ladenie) */ int alokacia(pole_retazcov *p_r, int pocet) *p_r = malloc(pocet * sizeof(retazec)); return (*p_r == NULL)? -1 : 0; /* int alokacia(pole_retazcov *p_r, int pocet) */ int re_alokacia(pole_retazcov *p_r, int novy_pocet) pole_retazcov pom; if (*p_r == NULL) if (alokacia(p_r, novy_pocet)) return -1; /* chyba */ pom = realloc(*p_r, sizeof(retazec) * novy_pocet); if (pom == NULL) return -1; else *p_r = pom; return 0; /* int re_alokacia(pole_retazcov *p_r, int novy_pocet) */ int pridaj_riadok(pole_retazcov *p_r, retazec s, int index) int dlzka = strlen(s) + 1; if (((*p_r)[index] = malloc(dlzka)) == NULL) return -1; strcpy((*p_r)[index], s);

return 0; /* int pridaj_riadok(pole_retazcov *p_r, retazec s, int index) */ int citaj_a_pridavaj(pole_retazcov *p_r, int *pocet, int *alokovane, int prir) char riadok[dlzka_riadku], *pom; puts("zadavaj retazce, posledny CTRL-Z na novom riadku"); do if ((pom = gets(riadok))!= NULL) if (*pocet + 1 > *alokovane) if (re_alokacia(p_r, *alokovane + prir)) puts("nedostatok pamate"); return -1; *alokovane += prir; if (pridaj_riadok(p_r, riadok, *pocet)) puts("nedostatok pamate"); return 1; (*pocet)++; while (pom!= NULL); return 0; /*int citaj_a_pridavaj(pole_retazcov *p_r, int *pocet, int *alokovane, int prir)*/ void zobrazuj(pole_retazcov p_r, int pocet) while (pocet--) puts(*p_r++); /* void zobrazuj(pole_retazcov p_r, int pocet) */ int main(void) int pocet = 0, alokovane = START, prirastok = PRIRASTOK; pole_retazcov p_ret = NULL; #if defined(ladenie) volno(); #endif /* defined(ladenie) */ if (alokacia(&p_ret, alokovane)) puts("nedostatok pamate"); return 1; if (citaj_a_pridavaj(&p_ret, &pocet, &alokovane, prirastok)) return 1; zobrazuj(p_ret, pocet); #if defined(ladenie) uvolni(&p_ret, pocet); volno();

#endif /* defined(ladenie) */ return 0; /* int main(void) */ V programe je funkcia volno() definovaná v závislosti na skutočnosti, či je definované makro LADENIE. Ide teda o podmienený preklad. Prečo sme ho zavádzali je ľahké. Vo fázy ladenia potrebujeme mať istotu, že pamäť, ktorú sme alokovaly, neskôr správne vraciame. Akonáhle je program odladený, nie je táto pomocná funkcia potrebná. Nemusíme ale vnášať chyby tým, že ju aj jej volanie bezhlavo zmažeme. Výhodnejšie je, premyslieť si takúto situáciu už pri návrhu programu. Potom ju, rovnako ako v príklade, budeme prekladať podmienene. Poznamenajme, že obe popísané dynamické dátové štruktúry môžeme modifikovať pridaním ďalších funkcií na zásobník, frontu,.... Pre podrobnejší popis dynamických dátových štruktúr doporučujeme skvelé dielo profesora Niclausa Wirtha Algoritmy a štruktúry údajov. Predchádzajúca kapitola Obsah Začiatok Nasledujúca kapitola