Alocarea Dinamică a Memoriei – Concepte de Bază 5
1. Obiectivele lecției:
- Să înțeleagă conceptul de alocare dinamică a memoriei.
- Să învețe diferențele dintre memoria statică și cea dinamică.
- Să implementeze exemple practice pentru alocarea și eliberarea memoriei în C++.
2. Ce este alocarea dinamică a memoriei?
- Definiție:
Alocarea dinamică a memoriei este procesul prin care un program alocă memorie în timpul execuției, pe măsură ce este necesar, folosind heap-ul (o zonă din memoria RAM). - De ce este necesară?
- Dimensiunea datelor nu este cunoscută la momentul compilării.
- Gestionarea eficientă a memoriei pentru structuri de date mari, cum ar fi vectorii dinamici, listele, arborii sau grafurile.
- Memoria în C++:
- Memorie statică: Alocată la momentul compilării (ex.: variabile globale sau statice).
- Memorie automată: Alocată pe stivă pentru variabile locale.
- Memorie dinamică: Alocată pe heap și gestionată manual de programator.
3. Cum funcționează alocarea dinamică în C++?
- Operatorii pentru alocare și eliberare:
- new: Alocă memorie pe heap.
- delete: Eliberează memoria alocată cu new.
- new[]: Alocă memorie pentru un vector.
- delete[]: Eliberează memoria alocată pentru un vector.
- Exemplu simplu de alocare și eliberare:
int* p = new int; // Alocă memorie pentru un int
*p = 42; // Stochează valoarea 42
delete p; // Eliberează memoria
4. Avantaje și dezavantaje
Avantaje | Dezavantaje |
Flexibilitate în gestionarea memoriei. | Necesită gestionare manuală (risc de scurgeri de memorie). |
Util pentru structuri de date dinamice. | Posibilitatea dereferențierii unui pointer invalid. |
Permite alocarea memoriei doar când este nevoie. | Poate consuma mai mult timp comparativ cu alocarea statică. |
5. Exemple practice
Exemplu 1: Alocarea dinamică a unei variabile
- Problema: Alocați memorie pentru o singură variabilă și lucrați cu ea.
- Implementare:
#include <iostream>
using namespace std;
int main() {
int* p = new int; // Alocare dinamică
*p = 10; // Atribuire valoare
cout << „Valoarea stocată: ” << *p << endl;
delete p; // Eliberare memorie
p = nullptr; // Evitarea pointerului dangling
return 0;
}
Exemplu 2: Alocarea dinamică a unui vector
- Problema: Creați un vector dinamic și calculați suma elementelor.
- Implementare:
#include <iostream>
using namespace std;
int main() {
int n;
cout << „Introduceți dimensiunea vectorului: „;
cin >> n;
int* vector = new int[n]; // Alocare dinamică
cout << „Introduceți elementele vectorului: „;
for (int i = 0; i < n; i++) {
cin >> vector[i];
}
int suma = 0;
for (int i = 0; i < n; i++) {
suma += vector[i];
}
cout << „Suma elementelor: ” << suma << endl;
delete[] vector; // Eliberare memorie
vector = nullptr;
return 0;
}
Exemplu 3: Alocarea dinamică a unei matrice
- Problema: Creați o matrice dinamică și calculați suma elementelor.
- Implementare:
#include <iostream>
using namespace std;
int main() {
int rows, cols;
cout << „Introduceți numărul de linii și coloane: „;
cin >> rows >> cols;
int** matrice = new int*[rows]; // Alocare pentru linii
for (int i = 0; i < rows; i++) {
matrice[i] = new int[cols]; // Alocare pentru coloane
}
cout << „Introduceți elementele matricei: ” << endl;
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
cin >> matrice[i][j];
}
}
int suma = 0;
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
suma += matrice[i][j];
}
}
cout << „Suma elementelor: ” << suma << endl;
for (int i = 0; i < rows; i++) {
delete[] matrice[i]; // Eliberare memorie pentru fiecare linie
}
delete[] matrice; // Eliberare memorie pentru matrice
matrice = nullptr;
return 0;
}
6. Gestionarea corectă a memoriei
- Eliberarea memoriei:
- Este responsabilitatea programatorului să elibereze memoria alocată dinamic folosind delete sau delete[].
- Evitarea pointerilor dangling:
- După eliberarea memoriei, setați pointerul la nullptr pentru a preveni dereferențierea unui pointer invalid.
- Verificarea alocării:
- Verificați întotdeauna dacă alocarea a avut succes:
int* p = new (nothrow) int;
if (!p) {
cout << „Alocarea a eșuat!” << endl;
}
- Detectarea scurgerilor de memorie:
- Utilizați unelte precum Valgrind pentru a detecta scurgerile de memorie.
7. Activități practice pentru elevi
- Creați un program care alocă dinamic un vector, găsește valoarea maximă și o afișează.
- Realizați un program care utilizează o matrice alocată dinamic pentru a calcula produsul scalar al două matrici.
- Implementați o listă simplu înlănțuită utilizând alocarea dinamică.
8. Scheme logice
- Flux pentru alocarea și eliberarea memoriei:
- Start -> Alocare memorie (new) -> Utilizare -> Eliberare memorie (delete) -> Stop.
- Diagrama de alocare pentru o matrice:
- Start -> Alocare linii -> Alocare coloane pentru fiecare linie -> Utilizare -> Eliberare coloane -> Eliberare linii -> Stop.
9. Concluzie
- Alocarea dinamică a memoriei este esențială pentru gestionarea eficientă a resurselor în programe complexe.
- Programatorul este responsabil pentru alocarea și eliberarea corectă a memoriei pentru a evita scurgerile și erorile.
- Practica și utilizarea responsabilă sunt esențiale pentru stăpânirea acestui concept.