21
Dynamick Dynamick á alokácia á alokácia pamäte pamäte v C v C ++ ++

Dynamick á alokácia pamäte v C ++

Embed Size (px)

DESCRIPTION

Dynamick á alokácia pamäte v C ++. Osnova prednášky. Dynamická alokácia - opakovanie Alokácia premennej Alokácia jednorozmerného poľa Alokácia viacrozmerných polí. Smerník. - PowerPoint PPT Presentation

Citation preview

DynamickDynamická alokácia pamäte á alokácia pamäte v Cv C++++

Osnova prednáškyOsnova prednášky

Dynamická alokácia - opakovanieDynamická alokácia - opakovanie Alokácia premennejAlokácia premennej Alokácia jednorozmerného poľaAlokácia jednorozmerného poľa Alokácia viacrozmerných políAlokácia viacrozmerných polí

SmerníkSmerník Smerník je dátový typ, ktorý uchováva je dátový typ, ktorý uchováva adresu v operačnej

pamäti. Na tejto adrese môže byť uložená premenná nejakého . Na tejto adrese môže byť uložená premenná nejakého typu, prípadne tam môže začínať nejaké pole. typu, prípadne tam môže začínať nejaké pole.

Alokácia pamäťového Alokácia pamäťového miestamiesta

Statická alokácia: : Pamäťové miesto sa alokuje už pri kompilácii a nie je možné Pamäťové miesto sa alokuje už pri kompilácii a nie je možné meniť jeho veľkosťmeniť jeho veľkosťJe vhodná vtedy, ak vopred presne vieme, koľko pamäte Je vhodná vtedy, ak vopred presne vieme, koľko pamäte budeme potrebovaťbudeme potrebovať

Dynamická alokácia::Pamäťové miesto sa vytvorí počas behu programuPamäťové miesto sa vytvorí počas behu programuJe vhodná vtedy ak:Je vhodná vtedy ak:

Vopred nevieme, koľko pamäte budeme potrebovaťVopred nevieme, koľko pamäte budeme potrebovaťPriestor, ktorPriestor, ktorý budeme v pamäti potrebovať, je príliš ý budeme v pamäti potrebovať, je príliš

veľký na to, aby sa zmestil do časti vyhradenej pre statické veľký na to, aby sa zmestil do časti vyhradenej pre statické alokáciealokácieUmožňuje lepšie sa prispôsobiť požiadavkám programu, resp. Umožňuje lepšie sa prispôsobiť požiadavkám programu, resp. užívateľa, znižuje riziko vzniku chýb spôsobených užívateľa, znižuje riziko vzniku chýb spôsobených presiahnutím vyhradenej pamäte a zabraňuje zbytočnému presiahnutím vyhradenej pamäte a zabraňuje zbytočnému plytvaniu pamäťouplytvaniu pamäťou

Alokácia pamäťového Alokácia pamäťového miestamiesta

Statická alokácia::

Začiatok programu: Začiatok programu:

Priebeh programu: Priebeh programu:

Inštrukcia 1:Inštrukcia 1:

Inštrukcia 2:Inštrukcia 2:

...... Dynamická alokácia::

Začiatok programu:Začiatok programu:

Priebeh programu:Priebeh programu:

Inštrukcia 1:Inštrukcia 1:

Inštrukcia 2:Inštrukcia 2:

Inštrukcia 3:Inštrukcia 3:

......

Alokácia a dealokácia Alokácia a dealokácia premennejpremennej

Alokácia sa robí sa pomocou príkazu sa robí sa pomocou príkazunew typAk chceme Ak chceme premennú premennú alokovaalokovať s priradením hodnoty:ť s priradením hodnoty:new typ(value)

Dealokácia premennej: premennej:delete pointer;

PrPríklad: Alokácia celočíselnej premennejíklad: Alokácia celočíselnej premennejint *cislo=new int;*cislo=10;cout<<“Na adrese “<<cislo<<“je ulozena hodnota “<<*cislo<<endl;delete cislo;

VVýýstup:stup:Na adrese 00480040 je ulozena hodnota 10

Alokácia a dealokácia Alokácia a dealokácia premennejpremennej

Príklad: Alokácia reálneho čísla:: Alokácia reálneho čísla:

float a=2.5, *b=new float(3.2), *c=new float;cout<<“a=“<<a<<“ b=“<<*b<<“ c=“<<*c<<endl;*c=a+*b;cout<<“a=“<<a<<“ b=“<<*b<<“ c=“<<*c<<endl;delete b;delete c;

VVýstup:ýstup:a=2.5 b=3.2 c=-4.31260e+008a=2.5 b=3.2 c=5.7

AlokAlokácia a dealokácia ácia a dealokácia premennejpremennej Príklad: Alokácia štruktúry: Alokácia štruktúry

typedef struct{

int x,y;} bod;int main(){

bod A={100,150};cout<<"Bod A ma suradnice: "<<A.x<<" "<<A.y<<endl;bod *B=new bod(A);(*B).x+=20;(*B).y-=40;cout<<"Bod B ma suradnice: "<<(*B).x<<" "<<(*B).y<<endl;delete B;return 0;

}Výstup:Výstup:Bod A ma suradnice: 100 150Bod B ma suradnice: 120 110

AlokAlokácia jednorozmerného ácia jednorozmerného poľapoľa

Pole s dĺžkou Pole s dĺžkou nn môžeme alokovať takto: môžeme alokovať takto:new typ[n]A dealokujeme ho:A dealokujeme ho:delete[] array

Príklad:: V Výpočet hodnôt funkcie ýpočet hodnôt funkcie f(x)=f(x)=xx22 na intervale na intervale <0,1><0,1>int n;cout<<"V kolkych bodoch sa ma funkcia vypocitat?"<<endl;cin>>n;float *x=new float[n],*fx=new float[n];for (int i=0;i<n;i++){

x[i]=i*(1./(n-1));fx[i]=x[i]*x[i];cout<<"f("<<x[i]<<")="<<fx[i]<<endl;

}delete[] x;delete[] fx;

AlokAlokácia jednorozmerného ácia jednorozmerného poľapoľa

Výstup:Výstup:V kolkych bodoch sa ma funkcia vypocitat?6f(0)=0f(0.2)=0.04f(0.4)=0.16f(0.6)=0.36f(0.8)=0.64f(1)=1

AlokAlokácia dvojrozmerného ácia dvojrozmerného poľapoľa Stratégia po riadkoch (pole prvkov typu T): (pole prvkov typu T):

Princíp::

Alokujeme jednorozmerné pole smerníkov na daný typAlokujeme jednorozmerné pole smerníkov na daný typ

Pre každý smerník tohto poľa alokujeme jednorozmerné pole Pre každý smerník tohto poľa alokujeme jednorozmerné pole prvkov daného typuprvkov daného typu

*T*T TT

*T*T

*T*T

*T*T

*T*T

TT TT TT TT TT TT TT TT

TT TT TT TT TT TT TT TT TT

TT TT TT TT TT TT TT TT TT

TT TT TT TT TT TT TT TT TT

TT TT TT TT TT TT TT TT TT

TT TT TT TT TT TT TT TT TT

AlokAlokácia dvojrozmerného ácia dvojrozmerného poľapoľa Stratégia po riadkoch – – alokácia poľa s rozmermi alokácia poľa s rozmermi mmnn::

Alokácia:Alokácia:typ **pole=new typ*[m];for (i=0; i<m; i++) pole[i]=new typ[n];

PPrístup k prvkom:rístup k prvkom:pole[i][j]

DealokDealokácia:ácia:for (i=0; i<m; i++) delete[] pole[i];delete[] pole;

AlokAlokácia dvojrozmerného ácia dvojrozmerného poľapoľa Stratégia jedného bloku (pole prvkov typu T): (pole prvkov typu T):

Princíp::

Alokujeme naraz celý blok prvkov daného typu potrebný na Alokujeme naraz celý blok prvkov daného typu potrebný na uchovanie dátuchovanie dát

Alokujeme jednorozmerné pole smerníkov na daný typAlokujeme jednorozmerné pole smerníkov na daný typ

Každý smerník z poľa nasmerujeme tak, aby ukazoval na začiatok Každý smerník z poľa nasmerujeme tak, aby ukazoval na začiatok príslušného riadkupríslušného riadku

TT TT TT TT TT TT TT TT

TT TT TT TT TT TT TT TT

TT TT TT TT TT TT TT TT

TT TT TT TT TT TT TT TT

TT TT TT TT TT TT TT TT

*T*T

*T*T

*T*T

*T*T

*T*T

Alokácia dvojrozmerného Alokácia dvojrozmerného poľapoľa

Stratégia jedného bloku: skutočné usporiadanie v pamäti: skutočné usporiadanie v pamäti

Alokácia poľa s rozmermi Alokácia poľa s rozmermi mmnn::typ *blok=new typ[m*n];typ **pole=new typ*[m];for (i=0; i<m; i++) pole[i]=blok+n*i;PrPrístup k prvkom:ístup k prvkom:pole[i][j]DealokDealokácia:ácia:delete[] pole;delete[] blok;

TT TT TT TT TT TT TT TT TT TT TT TT TT TT TT TT TT TT TT

*T*T *T*T *T*T *T*T *T*T

AlokAlokácia dvojrozmerného ácia dvojrozmerného poľapoľa

Porovnanie uvedených stratégií::

1. 1. Pri stratégii jedného bloku tvorí alokované pole súvislý blok v pamäti, pri stratégii po riadkoch to tak nemusí byť. , pri stratégii po riadkoch to tak nemusí byť. To je väčšinou výhodou, jediný problém môže nastať, ak už To je väčšinou výhodou, jediný problém môže nastať, ak už v pamäti nie je voľný súvislý blok s požadovanou veľkosťouv pamäti nie je voľný súvislý blok s požadovanou veľkosťou

2. 2. Stratégia jedného bloku je rýchlejšia, keďže pri nej len , keďže pri nej len dvakrát voláme new a dvakrát deletedvakrát voláme new a dvakrát delete[][]

3. 3. Stratégia po riadkoch je flexibilnejšia, ak by sme chceli , ak by sme chceli pole, v ktorom by jednotlivé riadky mali premenlivú dĺžkupole, v ktorom by jednotlivé riadky mali premenlivú dĺžku

Alokácia trojrozmerného Alokácia trojrozmerného poľapoľa Stratégia po riadkoch::

**T**T

**T**T

**T**T

*T*T

*T*T

*T*T

*T*T

*T*T

*T*T

*T*T

*T*T

*T*T

TT TT TT TT TT TT TT TT

TT TT TT TT TT TT TT TT

TT TT TT TT TT TT TT TT

TT TT TT TT TT TT TT TT

TT TT TT TT TT TT TT TT

TT TT TT TT TT TT TT TT

TT TT TT TT TT TT TT TT

TT TT TT TT TT TT TT TT

TT TT TT TT TT TT TT TT

TTTT

TT

TTTT

TT

TTTT

TT

TT TT TTTT TT TT

TT TT TTTT

TTTT

TT

TT

TT TT

TT TT TT

TT TT TT

TT TT

AlokAlokácia trojrozmerného ácia trojrozmerného poľapoľa

Stratégia jedného bloku::

TT TT TT TT

**TT **TT **TT **TT

**TT **TT **TT **TT

**TT **TT **TT **TT

**TT **TT **TT **TT

**T**T

**T**T

**T**T

**T**T

AlokAlokácia viacrozmerných ácia viacrozmerných polípolí

Ak sú všetky rozmery poľa okrem jedného známe v časeAk sú všetky rozmery poľa okrem jedného známe v čase kompilácie, môžeme alokovať viacrozmerné pole nasledujúcim kompilácie, môžeme alokovať viacrozmerné pole nasledujúcim spôsobom:spôsobom:typ (*pole)[const1][const2][const3]... = new typ[d][const1][const2][const3]...Dealokujeme klasickým spôsobomDealokujeme klasickým spôsobomdelete[] pole;

Príklad:: Alok Alokácia poľa celých čísel s rozmermi 5ácia poľa celých čísel s rozmermi 51010int n=5;int (*pole)[10]=new int[n][10];NasledujNasledujúci zápis úci zápis nie je dovolený!!int n=5;int m=10;int (*pole)[m]=new int[n][m];

Memory leakMemory leak

Ku každej dynamickej alokácii musí byť urobená príslušná dealokácia!!

Predstavme si situáciu, keď máme nejakú funkciu Predstavme si situáciu, keď máme nejakú funkciu ffvoid f(int n){

char *pole=new int[n];...

}Čo sa stane, ak vo funkcii f chýba dealokácia?

Lokálna premenná Lokálna premenná polepole zanikne, ale v pamäti ostane alokovaných zanikne, ale v pamäti ostane alokovaných nn pamäťových miest, ku ktorým už nie je možný prístup. Takéto pamäťových miest, ku ktorým už nie je možný prístup. Takéto miesto v pamäti sa nazýva miesto v pamäti sa nazýva memory leak a je častou a niekedy a je častou a niekedy ťažko odhaliteľnou programátorskou chybou.ťažko odhaliteľnou programátorskou chybou.

RozdielyRozdiely medzi alokáciou v C a medzi alokáciou v C a CC++++

V V C na alokáciu používame na alokáciu používame funkcie mallocmalloc(..) a (..) a freefree( ), zatiaľ ( ), zatiaľ čo v čo v C++ máme máme operátory newnew a a deletedelete

Operátor Operátor new umožňuje alokovať premennú aj s nastavením jej hodnoty (pri objektoch zavolá koštruktor), (pri objektoch zavolá koštruktor), mallocmalloc to to neumožňujeneumožňuje

Operátor Operátor delete pri objektoch zavolá ich deštruktor,, free free nie nie V C je možnosť realokovať, teda zmeniť veľkosť vyhradeného , teda zmeniť veľkosť vyhradeného

pamäťového miesta, v Cpamäťového miesta, v C++ to mo++ to možné nie ježné nie je malloc pri neúspešnej alokácii vráti hodnotu NULL, new

oznámi výnimku Operátory Operátory new[] a delete[] umožňujú priamu prácu s poľami, ,

čo čo mallocmalloc a a freefree neumožňujú neumožňujú newnew je rýchlejšie ako je rýchlejšie ako mallocmalloc, ale , ale freefree je rýchlejšie ako je rýchlejšie ako deletedelete. .

AleAle celková kombinácia new/delete je rýchlejšia ako malloc/free..

ZhrnutieZhrnutie

Dynamická alokácia je vhodná vtedy, ak vopred nevieme, koľko pamäte budeme potrebovať, alebo ak chceme zabrániť vytváraniu kópií premenných.

Alokácia a dealokácia premenných v C++ sa robí pomocou new a delete, polia sa alokujú pomocou new[] a delete[]

Operátor new umožňuje priamo nastaviť hodnotu premennej

Alokácia viacrozmerných polí sa môže robiť po riadkoch alebo pomocou jedného bloku