Puntatori e memoria

Gestione della memoria dinamica

Lo storage dinamico serve quando dimensione o lifetime non sono noti alla compilazione.

Che cos’è Gestione della memoria dinamica?

Lo storage dinamico serve quando dimensione o lifetime non sono noti alla compilazione.

Alloca un array a runtime e rilascialo correttamente.

Punti importanti

  • Ogni puntatore deve riferirsi a un oggetto vivo compatibile o essere null.
  • Ogni allocation posseduta va liberata una sola volta.
  • Esprimi chiaramente ownership e const.

Esempi di codice C e C++

C
Esegui →
main.c
#include <stdio.h>
#include <stdlib.h>

int main(void) {
    size_t count = 5;
    int *values = calloc(count, sizeof *values);
    if (!values) return 1;
    for (size_t i = 0; i < count; ++i) values[i] = (int)(i * i);
    printf("last=%d\n", values[count - 1]);
    free(values);
    return 0;
}
Output previsto
last=16
C++
Esegui →
main.cpp
#include <iostream>
#include <vector>

int main() {
    std::vector<int> values(5);
    for (std::size_t i = 0; i < values.size(); ++i) values[i] = static_cast<int>(i * i);
    std::cout << "last=" << values.back() << '\n';
}
Output previsto
last=16

Confronto tra C e C++

C abbina malloc/calloc a free e controlla gli errori; std::vector possiede e libera automaticamente, anche con exception.

C

Ownership e cleanup sono convenzioni manuali.

C++

Container e RAII codificano ownership e cleanup nel lifetime.

Esercizi pratici

Esegui entrambe le versioni e modificale per osservare le diverse garanzie.

  • Testa null e fallimenti di allocation.
  • Usa AddressSanitizer e UndefinedBehaviorSanitizer.
  • Documenta ownership di ogni puntatore.