Didaxis
lecție · Informatică

Alocarea dinamică

Creare și eliberare de noduri în memorie.

Se face în:
Clasa a X-a
Clasa a XI-a
Actualizat la: 30 octombrie 2026
1pe scurtstratul 1 din 2 · rezumatul lecției

Pe scurt

Alocarea dinamică rezervă memorie în timpul execuției, în zona heap, când nu știm dinainte câte elemente vor fi necesare. new obține spațiu și construiește obiectul, iar delete distruge obiectul creat printr-un new corespunzător. Un pointer păstrează adresa obiectului, nu obiectul însuși.

Desen la lecția „Alocarea dinamică”
2în detaliustratul 2 din 2 · pentru clasă și Bacalaureat

În detaliu

Alocarea dinamică rezervă memorie în timpul execuției, în zona numită heap, când nu se cunoaște dinainte câte elemente vor fi necesare sau cât timp trebuie să existe un obiect. Operatorul new obține spațiul și construiește obiectul, întorcând adresa lui, iar delete eliberează un obiect creat cu new. Pentru tablouri se folosesc new tip[n] și delete[] p. Un pointer păstrează adresa obiectului, nu obiectul însuși: variabila int *p conține o adresă, iar *p este valoarea de la acea adresă. Memoria alocată rămâne rezervată până la delete, chiar dacă pointerul care o indica a fost pierdut; o memorie neeliberată se numește scurgere de memorie. După delete p, vechea adresă nu mai poate fi folosită, iar atribuirea p = nullptr previne folosirea accidentală. Un același obiect nu se eliberează de două ori. Variabilele locale obișnuite, spre deosebire de cele alocate dinamic, sunt create și șterse automat la intrarea și ieșirea din bloc.

Exemplul 1 — un întreg alocat dinamic.

#include <iostream>
using namespace std;
int main() {
    int* p = new int(7);
    cout << *p;
    delete p;
    p = nullptr;
    return 0;
}

new int(7) alocă un întreg inițializat cu 7 și întoarce adresa lui; *p citește valoarea 7, care este afișată. După delete p, zona este eliberată, iar p = nullptr arată că pointerul nu mai indică niciun obiect.

Exemplul 2 — un tablou cu dimensiune cunoscută la execuție. Dacă dimensiunea este citită sau calculată, tabloul se alocă cu new int[n]. Pentru și valorile 3, 1, 4, 1, suma lor este 9:

int n = 4;
int* v = new int[n]{3, 1, 4, 1};
int suma = 0;
for (int i = 0; i < n; ++i)
    suma += v[i];
cout << suma;
delete[] v;

Secvența afișează 9. Tabloul alocat cu new[] se eliberează cu delete[], nu cu delete; folosirea formei greșite are comportament nedefinit. Spre deosebire de un tablou declarat int v[100], dimensiunea poate fi aleasă la execuție și nu este limitată de o constantă scrisă în program.

Exemplul 3 — noduri alocate dinamic. După declarația struct Nod { int valoare; Nod* urmator; };, expresia Nod* p = new Nod{7, nullptr}; construiește un nod cu valoarea 7 și fără succesor. Nodul există până la delete p;, deci supraviețuiește funcției care l-a creat și poate fi legat de alte noduri. Înainte de eliberare, legăturile nodurilor care îl indică trebuie corectate, altfel ele ar păstra o adresă invalidă. Fiecare nod al unei liste de noduri este eliberat printr-un delete propriu; dacă se eliberează capul și se pierde adresa restului, celelalte noduri devin scurgeri de memorie. În C++ modern, containerele standard și obiectele care își gestionează singure resursele reduc acest risc.

Exemplul 4 — o listă de trei noduri, creată, parcursă și eliberată. Nodurile se adaugă la începutul listei, în ordinea 3, 2, 1; la fiecare pas noul nod devine cap și păstrează vechiul cap ca succesor.

Nod* cap = nullptr;
for (int x = 3; x >= 1; --x)
    cap = new Nod{x, cap};
int s = 0;
for (Nod* p = cap; p != nullptr; p = p->urmator)
    s += p->valoare;
cout << s;
while (cap != nullptr) {
    Nod* urm = cap->urmator;
    delete cap;
    cap = urm;
}

După primul pas lista este , după al doilea , după al treilea . Parcurgerea adună și afișează 6. La eliberare, adresa succesorului se reține în urm înainte de delete cap, pentru că după ștergere câmpul cap->urmator nu mai poate fi citit. Cazuri-limită: delete aplicat unui pointer nul nu face nimic, iar new int[0] este permis și întoarce o adresă validă care nu poate fi dereferențiată. Dacă new nu găsește memorie suficientă, aruncă excepția std::bad_alloc.

Greșeli frecvente

  • Greșit: memoria alocată cu new se eliberează automat la sfârșitul blocului.
    Corect: se eliberează numai prin delete, altfel apare o scurgere de memorie.
  • Greșit: un tablou alocat cu new[] se eliberează cu delete.
    Corect: se folosește delete[].
  • Greșit: după delete p, pointerul p poate fi citit în siguranță.
    Corect: obiectul nu mai există; p trebuie anulat sau reatribuit.
în contul tăuPremium

Testează-te pe această lecție

Lecția o citești aici, fără cont. Testele pe lecții și capitole sunt în cont, cu grile originale Didaxis și explicația fiecăreia: gratuit 10 grile pe zi, fără limită cu Premium, 49 de lei pe lună pentru fiecare copil.

Înainte și după

Surse și referințe

Redactare proprie, conform programei:

  • OMECI 5099/2009, anexa 5, Informatică, p. 4–5, clasa X intensiv; rocnee.eu
  • OMECI 5099/2009, anexa 5, Informatică, p. 4–5, clasa XI intensiv; rocnee.eu

Documente consultate

  • Programa școlară de informatică intensiv, clasa a X-a (OMECI 5099/2009, anexa 5), CNCE, p. 4–5; rocnee.eu
  • cppreference, C++ language, New expression and Delete expression, en.cppreference.com/w/cpp/language/new

Desene: Redactare proprie (desen original), conform OMECI 5099/2009, anexa 5, Informatică X intensiv, p. 4–5; rocnee.eu

lecțiile sunt gratuite

Ai citit lecția. Acum verifică-te.