Curs C++ | Sectiunea 23 – Alocare de memorie

 

Am discutat anterior despre tipul void folosit in functii in care specificam daca nu exista parametrii sau nu exista un tip returnat.

void function(void);

Desi tipul void nu reprezinta o valoare utila, putem spre exemplu sa declaram un pointer de acest tip.

void *ptr;

❓ Vine intrebarea, cum putem folosi un pointer care nu indica la nimic si mai mult, de ce avem nevoie de un astfel de pointer? Acest tip de pointer poarta numele de pointer amorf (amorphous pointer), sugerand ideea ca poate indica la orice tip de date.

❗ Un pointer de tip *void nu poate fi folosit cu operatorul de dereferentiere!

Totusi, cum asignam o valoare unui astfel de pointer. Daca incercam sa folosim pur si simplu operatorul de asignare, dupa cum urmeaza vom primi eroarea invalid conversion from ‘void*’ to ‘int*.

void *ptr; // void pointer 
int *ptr1; // int pointer
int x = 10; // int variable initialization
ptr = &x;
ptr1 = ptr; // assigning void pointer to int pointer
std::cout << "*ptr1 = " <<*ptr1<< std::endl;

Suntem nevoiti sa facem un cast la tipul corespunzator de date, in cazul nostru tipul int, in momentul asignarii. Nu va facei griji, vom discuta mai in amanunt despre acest proces intr-o sectiune separata.

ptr1 = (int *)ptr;

 

Alocarea memoriei

💾 In exemplele folosite pana acum, management-ul memoriei a fost ceva considerat auomat de noi. Toate procesele asociate cu alocarea memoriei au fost realizate de compilator fara sa stim cum functionaza. Iar acest lucru nu este gresit, daca folosim un limbaj de programare de nivel inalt (high level), unde compilatoarele sunt proiectate sa preia aceste probleme de la developer.

Deseori, se poate intampla sa avem nevoie sa stim exact cata memorie este folosita, mai ales cand nu stim dimensiunea datelor ce urmeaza sa le procesam. Pentru management-ul alocarii si eliberarii memoriei, C++ ne pune la dispozitie doi noi operatori.

  • new
  • delete

 

New

💡 Operatorul new este folosit pentru crearea unei noi zone de memorie. Cand memoria alocata nu mai este folosita, ideal ar fi sa o returnam sistemului de operare, folosind operatorul delete.

float *array = new float[10];
int data = new int;
  • trebuie specificatii exacte in legatura cu noua entitate creata; daca entitatea creata este un sir, dimensiunea sirului trebuie mentionata (in exemplul nostru fiind 10)
  • operatorul new returneaza un pointer de un tip corespunzator entitatii noi create
  • noua memorie alocata nu este initializata, deci ne putem astepta sa contina informatii aleatoare (garbage)

 

Delete

Cand nu mai avem nevoie de acea memorie, o eliberam (free) folosind operatorul delete, dupa cum urmeaza.

delete [] array;
delete data;
  • folosim delete [] daca ne dorim sa eliberam memoria alocata unui sir, altfel, pentru o simpla variabila, folosim delete
  • se poate elibera intreaga zona de memorie alocata, nu doar o parte
  • dupa executarea instructiunii delete, toti pointerii care indica la date aflate in acea zona de memorie devin ilegali; incercarea de a ii folosi poate rezulta in comportament nedefinit (undefined behaviour) si intreruperea anormala a programului

❗ Modul de lucru al sirurilor dinamice (dynamic arrays) create folosind operatorul new nu este diferita de cea a sirurilor folosite normale pana acum. Accesarea elementelor se face tot prin [ ] impreuna cu instructiunea for spre exemplu.

Prin acest mod de control al memoriei putem folosi exact cat este nevoie si nu mai mult. Putem face spre exemplu, dimensiunea sirului ca depinzand de o variabila si aceea fiind citita de la tastatura. Astfel, vom aloca de fiecare data exact cata memorie este folosita.

 

Aici se termina si aceasta sectiune 🙂 . Pentru intrebari suplimentare puteti folosi informatiile de aici.

➡ Sectiunea anterioara:Curs C++ | Sectiunea 22 – Functii Supraincarcate(Overloaded)

➡ Sectiunea urmatoare:Curs C++ | Sectiunea 24 – Siruri de pointeri

You may also like...