Sunteți pe pagina 1din 14

Clase de memorare

Definiții:
Variabilele declarate în afara oricărei funcții sunt variabile globale.
Variabilele declarate în interiorul unui bloc sunt variabile locale.
Porțiunea de cod în care o variabilă este accesibilă reprezintă scopul (domeniul de
vizibilitate) al variabilei respective.

Parametri formali ai unei funcții sunt variabile locale ale funcției respective.
Domeniul de vizibilitate al unei variabile locale este blocul în care variabila respectivă
este definită.
În situația în care numele unei variabile globale coincide cu numele variabilei locale,
varibila locală o “maschează” pe cea globală

Vezi programul variabile.cpp

04/30/2021 1
În cazul variabilelor locale, compilatorul alocă memorie în momentul excuției
blocului sau funcției în care acestea sunt definite. Când execuția funcției sau
blocului se termină, se eliberează memoria pentru aceasta și valorile pentru
variabilele locale se pierd.

Definiții:
Timpul de viață al unei variabile locale este durata de execuție a blocului(sau a
funcției) în care aceasta este definită.
Timpul de viață al unei variabile globale este durata de execuție a programului.

Vezi programul variabile1.cpp

04/30/2021 2
Moduri de alocare a memoriei
Alocarea memoriei(interne) se poate realiza astfel:

- Alocare statică;
- Alocare dinamică;
- Alocare pe stivă.

Alocarea statică se face în următoarele cazuri:


-Pentru instrucțiunile de control propriu-zise;
-Pentru variabilele globale și variabilele declarate în mod explicit static.

Alocarea memoriei pe stivă se face pentru variabilele locale.

Alocarea dinamocă de memorie în mod explicit se face cu ajutorul


funcțiilor de alocare dinamică, care se găsesc în headerul <alloc.h>(în
limbajul C), sau cu ajutorul operatorului new(în limbajul C++).

04/30/2021 3
Așa după cum se cunoaște(sau ar trebui să cunoaștem), pentru toate tipurile de
date(simple sau structurate), la declararea acestora, compilatorul alocă automat
un număr de locații de memorie corespunzător tipului datei.

Vezi programul aloc_stat.cpp

Pentru cazul datelor a căror dimensiune nu se cunoaște apriori, sau variază în


limite largi se recomandă utilizarea alocării dinamice a memoriei. Acest lucru
înseamnă că memoria nu se alocă în momentul compilării ci în momentul
execuției.

04/30/2021 4
Operatorii de alocare dinamică de memorie în C++

În limbajul C++ alocarea dinamică de memorie și elibararea ei se realizează cu


operatorii new și respectiv delete.
Operatorul new este un operator unar, ce oferă posibilitatea alocării dinamice
de memorie atât pentru date de tip predefinit, cât și pentru date de tip definit
de utilizator. Operatorul returnează un pointer la zona de memorie alocată.
Dacă nu există suficientă memorie și alocarea eșuează, operatorul new
returnează pointerul NULL.
Operatorul delete eliberează zona de memorie spre care pointează
argumentul său.

04/30/2021 5
Sintaxa:

<tipdata_pointer> = new <tipdata>; // alocare data simpla


<tipdata_pointer> = new <tipdata>(<val_initializare>); //alocare cu initializare
<tipdata_pointer> = new <tipdata>[nr_elem];//alocare tablou

delete <tipdata_pointer>;//elibereaza zona de memorie alocata dinamic


delete [nr_elem]<tipdata_pointer>;//elibereaza zona de memorie alocata dinamic
tabloului

<tipdata> reprezintă tipul datei (predefinit sau obiect) pentru care se alocă dinamic
memorie, iar < tipdata_pointer> este o variabilă pointer către tipul <tipdata>.

04/30/2021 6
Exemplu 1: se alocă dinamic memorie pentru o dată de tip întreg:
int *pint; // pointer către un un întreg
pint = new int;
//sau
int &i = *new int;

Exemplu 2: se alocă dinamic memorie pentru o dată reală, dublă precizie și se


inițializează cu valoarea15.3
double *p;
p = new double(15.3);
//sau
double &p=*new double(15.3);

Programul aloc_din.cpp, atestat0.cpp

04/30/2021 7
Text preluat de pe adresa: http://alocaredinamica.eu5.org/index.html

Memoria dinamică solicitată de programul nostru este alocată de sistem din


memoria heap.Cu toate acestea,memoria calculatorului este o resursă limitată şi
poate fi epuizată.De aceea este foarte important să se verifice dacă alocarea a fost
reuşită. C++ oferă două metode standard de a verifica dacă alocarea a fost facută
cu succes:
- Una este manipularea excepţiilor.Utilizând această metodă,o excepţie de tipul
bad_alloc este aruncată când alocarea eşuează.Dacă o excepţie este aruncată şi nu
este manipulată de un manipulator specific,execuţia programului este oprită.
-Cealaltă metodă este cunoscută ca nothrow,iar ceea ce se întâmplă atunci cănd o
alocare a memoriei eşuează, este că în loc să se arunce o excepție bad_alloc sau
să se termine programul,pointerul returnat de new este un pointer nul,iar
programul îşi continuă execuţia.Această metodă poate fi specificată utilizînd un
obiect special numit nothrow,declarat în ca atribut al lui new:

Programul atestat0.cpp

04/30/2021 8
CONCLUZIE 1:
Pentru a putea testa valoarea pointerului, trebuie neaparat sa utilizăm nothrow!!!

Memoria alocatǎ cu new si controlatǎ de pointerul respectiv în schimb nu este


eliberatǎ automat. Respectiva zonǎ de memorie devine indisponibilǎ generând o
gaurǎ de memorie(memory leak). Zona de memorie nu se mai "reface" nici când
programul se terminǎ.

CONCLUZIE 2:
să ștergem cu operatorul delete variabilele alocate dinamic.

04/30/2021 9
Funcții recursive
Definiție: o funcție se numește funcție recursivă(sau pe scurt recursivă) dacă ea
se autoapelează fie direct(în definiția ei se face apel la ea însăși), fie indirect (prin
apelul altor funcții)
Limbajele C și C++ dispun de mecanisme speciale care permit suspendarea
execuției unei funcții, salvarea datelor și reactivarea execuției la un alt moment
de timp. Pentru fiecaer apel al funcției, parametrii și variabilele se memorează în
stivă, având valori distincte la fiecare reapelare.

Proiectarea unui algoritm recursiv trebuie să asigure ieșirea din recursivitate. De


aceea apelul recursiv este inclus într-o structură de control de decizie sau
repetitivă.

Exemplul clasic de funcție recursivă este calculul factorialului:


fact(n)=1, dacă n=0 (parte a procesului recursiv care nu se definește prin el
însuși)
fact(n)=n*fact(n-1), dacă n>0

Programul factorial.cpp
04/30/2021 10
04/30/2021 11
Pointeri către funcții
Pointerii către funcții sunt variabile pointer care conțin adresa de început a codului
executabil al unei funcții. Pointerii către funcții permit:
-transferul ca parametru al adresei unei funcții;
- apelul unei funcții cu ajutorul unui pointer către acesta.

Declarația unui pointer către funcție are forma:

<tip> (*<nume_point>)(<lista_declar_param_formali>);
unde:
nume_point este un pointer de tipul “funcție cu rezultatul tipul_valorii_întoarse”. În
declarația precizată mai sus trebuie remarcat rolul parantezelor, penru a face distincție
între declarația unei funcții care întoarce un pointer și declarația unui pointer de funcție:

tip_val_intoarse * nume_point (lista_declar_param_formali);


tip_val_intoarse (* nume_point) (lista_declar_param_formali);

04/30/2021 12
Exemplu:

int f(double , int ); //prototipul funcției f


int (*pf) (double, int); //declararea pointerului pf către funcția f
int i,j;
double d;
pf = f; //atribuie adresa codului executabil al funcțieif pointerului pf
j = *pf(d,i); //apelul funcției f, folosind pointerul către funcție, pf

04/30/2021 13

mulțumesc!

04/30/2021 14

S-ar putea să vă placă și