La gestió de memòria és un aspecte crucial en la programació en C++, ja que permet als programadors controlar com s'assigna i s'allibera la memòria durant l'execució del programa. Una gestió de memòria eficient pot millorar significativament el rendiment i la fiabilitat del teu codi. En aquesta secció, explorarem els conceptes clau de la gestió de memòria en C++.

Continguts

Memòria Estàtica vs. Memòria Dinàmica

Memòria Estàtica

  • Definició: La memòria estàtica es reserva en temps de compilació i es manté durant tota l'execució del programa.
  • Exemples: Variables globals, variables estàtiques dins de funcions.
  • Avantatges: Senzillesa i eficiència en l'assignació.
  • Desavantatges: Falta de flexibilitat, ja que la mida de la memòria ha de ser coneguda en temps de compilació.

Memòria Dinàmica

  • Definició: La memòria dinàmica es reserva en temps d'execució, permetent una major flexibilitat.
  • Exemples: Memòria assignada amb new o malloc.
  • Avantatges: Flexibilitat per assignar memòria segons les necessitats del programa.
  • Desavantatges: Requereix una gestió manual per evitar fuites de memòria.

Assignació Dinàmica de Memòria

L'assignació dinàmica de memòria permet als programes sol·licitar memòria durant l'execució. En C++, això es fa principalment amb els operadors new i delete.

Exemple Bàsic

#include <iostream>

int main() {
    // Assignació dinàmica d'un enter
    int* p = new int;
    *p = 10;
    std::cout << "Valor de p: " << *p << std::endl;

    // Alliberament de la memòria
    delete p;

    return 0;
}

Explicació

  • new int: Assigna memòria per a un enter.
  • *p = 10: Assigna el valor 10 a la memòria assignada.
  • delete p: Allibera la memòria assignada.

Gestió de Memòria amb new i delete

Arrays Dinàmics

#include <iostream>

int main() {
    // Assignació dinàmica d'un array
    int* arr = new int[5];
    for (int i = 0; i < 5; ++i) {
        arr[i] = i * 2;
    }

    for (int i = 0; i < 5; ++i) {
        std::cout << arr[i] << " ";
    }
    std::cout << std::endl;

    // Alliberament de la memòria
    delete[] arr;

    return 0;
}

Explicació

  • new int[5]: Assigna memòria per a un array de 5 enters.
  • delete[] arr: Allibera la memòria assignada per l'array.

Fuites de Memòria

Una fuita de memòria ocorre quan la memòria dinàmica assignada no és alliberada correctament, provocant que la memòria no estigui disponible per a futures assignacions.

Exemple de Fuita de Memòria

#include <iostream>

void memoryLeak() {
    int* p = new int;
    *p = 10;
    // No hi ha delete, per tant, la memòria no s'allibera
}

int main() {
    memoryLeak();
    return 0;
}

Solució

#include <iostream>

void memoryLeak() {
    int* p = new int;
    *p = 10;
    delete p; // Alliberament de la memòria
}

int main() {
    memoryLeak();
    return 0;
}

Smart Pointers

Els smart pointers són una característica de C++11 que ajuden a gestionar la memòria automàticament, evitant fuites de memòria.

Tipus de Smart Pointers

  • std::unique_ptr: Manté la propietat exclusiva d'un objecte.
  • std::shared_ptr: Permet la propietat compartida d'un objecte.
  • std::weak_ptr: Proporciona una referència no propietària a un objecte gestionat per std::shared_ptr.

Exemple amb std::unique_ptr

#include <iostream>
#include <memory>

int main() {
    std::unique_ptr<int> p(new int(10));
    std::cout << "Valor de p: " << *p << std::endl;

    // No cal alliberar la memòria manualment
    return 0;
}

Exercicis Pràctics

Exercici 1: Assignació Dinàmica d'Arrays

Escriu un programa que assigni dinàmicament un array de 10 enters, assigni valors a cada element i imprimeixi els valors.

Solució

#include <iostream>

int main() {
    int* arr = new int[10];
    for (int i = 0; i < 10; ++i) {
        arr[i] = i + 1;
    }

    for (int i = 0; i < 10; ++i) {
        std::cout << arr[i] << " ";
    }
    std::cout << std::endl;

    delete[] arr;
    return 0;
}

Exercici 2: Ús de std::shared_ptr

Escriu un programa que utilitzi std::shared_ptr per gestionar la memòria d'un objecte.

Solució

#include <iostream>
#include <memory>

class MyClass {
public:
    MyClass() { std::cout << "Constructor" << std::endl; }
    ~MyClass() { std::cout << "Destructor" << std::endl; }
};

int main() {
    std::shared_ptr<MyClass> ptr1 = std::make_shared<MyClass>();
    {
        std::shared_ptr<MyClass> ptr2 = ptr1;
        std::cout << "Inside block" << std::endl;
    }
    std::cout << "Outside block" << std::endl;

    return 0;
}

Conclusió

La gestió de memòria és un aspecte fonamental en la programació en C++. Comprendre com assignar i alliberar memòria correctament, així com utilitzar eines com els smart pointers, pot ajudar a evitar fuites de memòria i millorar el rendiment del teu codi. Practica aquests conceptes amb els exercicis proporcionats per consolidar el teu coneixement.

© Copyright 2024. Tots els drets reservats