> For the complete documentation index, see [llms.txt](https://ase.lucianvilcea.ro/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://ase.lucianvilcea.ro/home/programare-orientata-obiect/recapitulare-c++/markdown.md).

# Gestionarea memoriei

Memoria este una dintre resursele fundamentale pe care orice program le utilizează. În C++, înțelegerea modului în care funcționează memoria poate face diferența dintre un program eficient și unul plin de bug-uri sau cu o performanță nesatisfăcătoare. Când programul tău rulează, computerul îi alocă spațiu în memoria RAM - imaginează-ți memoria ca pe un dulap cu multe sertare (bytes). În acest "dulap", programul poate stoca variabile, structuri de date și tot ce are nevoie pentru a funcționa. Fiecare variabilă poate ocupa unul sau mai multe "sertare".

Pentru a eficientiza accesul la aceste valori, memoria gestionată în cadrul unui program C++ se împarte în două zone principale: **stack** și **heap**.&#x20;

**Stack**-ul este o zonă de memorie organizată și gestionată automat, care funcționează după principiul LIFO (Last In, First Out) - ultimul element adăugat este primul element procesat. Aici sunt stocate variabile locale din funcții, parametrii funcțiilor, adrese de returnare și alte elemente alocate static. Este important de reținut că memoria stack este limitată și nu este concepută pentru a gestiona volume mari de date. Exemplul de cod de mai jos alocă trei variabile în mod static, în stack.

```cpp
#include <iostream>
int main() {
    int x = 10;
    double y = 3.14;
    char c = 'A';
    
    std::cout<< x << " " << y << " " << c;
    
    return 0;
}
```

În cazul programului de mai sus, memoria stack arată astfel:

<figure><img src="https://2341277153-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FDZQFKa1I5bTOOhuhKP3Y%2Fuploads%2F6ghI1tze3R5aMpHGBWHI%2Fimage.png?alt=media&amp;token=e5ff3b5c-ab30-491e-ac2e-768c593a7f9d" alt=""><figcaption></figcaption></figure>

În momentul în care funcția main începe execuția, în memoria stack se adaugă o înregistrare care specifică faptul că, din acel punct, toate intrările din stivă aparțin funcției main. Ulterior, adăugarea de variabile noi se execută peste această intrare și vor fi disponibile atâta timp cât funcția main încă nu și-a terminat execuția. La întâlnirea instrucțiunii `return 0`,  memoria stack este golită automat, de sus în jos, până la întâlnirea intrării aferentă stack frame-ului curent.

**Heap**-ul este o zonă de memorie neorganizată, unde datele sunt alocate "la grămadă" - de unde și numele de heap. Alocarea și dealocarea zonelor de memorie heap revine exclusiv în sarcina programatorului și este important ca acestea să fie făcute corect și complet. Deși prelucrarea datelor din heap este mult mai lentă decât a celor din stack, avantajele principale în folosirea acestei zone sunt reprezentate de capacitatea de stocare mult mai mare, precum și posibilitatea de a permite obiectelor să "supraviețuiască" în afara funcțiilor care le-au declarat. Blocul de cod de mai jos alocă dinamic o variabilă și prelucrează valoarea ei. **Totuși, exemplul este incomplet!**

```cpp
#include <iostream>

int main() {
    int* x= new int;
    *x= 50;
    
    std::cout << *x<< " " << &x;
    
    return 0;
}
```

Memoria stack și heap în urma execuției programului poate fi reprezentată astfel:

<figure><img src="https://2341277153-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FDZQFKa1I5bTOOhuhKP3Y%2Fuploads%2FbUiGz5RK7EvId2Cmjgvy%2Fimage.png?alt=media&amp;token=e321663e-ee1d-40b0-bf06-d708c04607f0" alt=""><figcaption></figcaption></figure>

Observăm apariția a două simboluri noi. Aceste simboluri se numesc **operatori** și au o mare importanță în accesarea corectă a variabilelor alocate dinamic.

* `&` - operatorul de adresare. Acesta ne spune **unde se află variabila** în memorie. Returnează adresa RAM a variabilei respective (în cazul nostru, x00112233)
* `*` - operatorul de dereferențiere. Acesta ne spune **ce valoare se află în acea variabilă.** Returnează valoarea efectivă a variabilei (în cazul nostru, 50).

**Important:** variabilele alocate în heap nu sunt identificate după nume, ci doar după adresa lor. Din acest motiv, pentru orice obiect alocat dinamic în heap, se reține în stack o variabilă corespondentă care face posibilă legătura cu această zonă de memorie. Această variabilă specială poartă numele de **pointer**.&#x20;

Și în cazul memoriei alocate dinamic, stack-ul funcționează după același principiu: la apelarea funcției main se generează o intrare pentru un stack frame, se alocă (tot pe stack) memoria pentru pointer, iar la intâlnirea instrucțiunii de returnare, se elimină, de sus în jos, tot conținutul stack-ului până la întâlnirea intrării aferente stack frame-ului. Observăm, însă, o problemă!&#x20;

<figure><img src="https://2341277153-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FDZQFKa1I5bTOOhuhKP3Y%2Fuploads%2FmkKwyefPeCyhm6pYAhcG%2Fimage.png?alt=media&amp;token=48a58e07-0b9c-49fd-8425-11d9267a067e" alt=""><figcaption></figcaption></figure>

După încheierea execuției funcției main și resetarea stack-ului până la cel mai apropiat stack frame, pointer-ul care reținea adresa variabilei alocate în heap a fost și el eliminat, ceea ce înseamnă că zona de memorie alocată inițial pentru a reține valoarea 50 nu mai este accesibilă prin pointer. Totodată, ea nu are un nume propriu pentru a putea face posibilă identificarea, dar nici nu a fost eliminată automat, deoarece memoria heap nu beneficiază de acest lucru. Așadar, am ajuns în situația în care avem o variabilă alocată în memorie, dar pentru care nu există nicio modalitate prin care să poată fi accesată. Acest tip de problemă poartă numele de **memory leak**.&#x20;

Rezolvarea acestei probleme presupune gestionarea manuală a memoriei aferente acelei variabile.&#x20;

```cpp
#include <iostream>

int main() {
    int* x= new int;
    *x= 50;
    
    std::cout << *x<< " " << &x;
    
    delete x; //IMPORTANT!
    
    return 0;
}
```

Prin introducerea instrucțiunii `delete x`, compilatorul va executa dealocarea memoriei heap aferente pointerului `x` (**atenție**, nu îl șterge pe `x`  din stack, ci zona de memorie heap stocată la adresa din `x`) înainte de întâlnirea instrucțiunii de returnare și golirea stack-ului până la intrarea aferentă stack frame-ului.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://ase.lucianvilcea.ro/home/programare-orientata-obiect/recapitulare-c++/markdown.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
