|

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?

  1. 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).
  2. 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.
  3. 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++?

  1. 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.
  2. 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

AvantajeDezavantaje
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

  1. Problema: Alocați memorie pentru o singură variabilă și lucrați cu ea.
  2. 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

  1. Problema: Creați un vector dinamic și calculați suma elementelor.
  2. 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

  1. Problema: Creați o matrice dinamică și calculați suma elementelor.
  2. 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

  1. Eliberarea memoriei:
    • Este responsabilitatea programatorului să elibereze memoria alocată dinamic folosind delete sau delete[].
  2. Evitarea pointerilor dangling:
    • După eliberarea memoriei, setați pointerul la nullptr pentru a preveni dereferențierea unui pointer invalid.
  3. Verificarea alocării:
    • Verificați întotdeauna dacă alocarea a avut succes:

int* p = new (nothrow) int;

if (!p) {

    cout << „Alocarea a eșuat!” << endl;

}

  1. Detectarea scurgerilor de memorie:
    • Utilizați unelte precum Valgrind pentru a detecta scurgerile de memorie.

7. Activități practice pentru elevi

  1. Creați un program care alocă dinamic un vector, găsește valoarea maximă și o afișează.
  2. Realizați un program care utilizează o matrice alocată dinamic pentru a calcula produsul scalar al două matrici.
  3. Implementați o listă simplu înlănțuită utilizând alocarea dinamică.

8. Scheme logice

  1. Flux pentru alocarea și eliberarea memoriei:
    • Start -> Alocare memorie (new) -> Utilizare -> Eliberare memorie (delete) -> Stop.
  2. 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.

Similar Posts

Lasă un răspuns

Adresa ta de email nu va fi publicată. Câmpurile obligatorii sunt marcate cu *