La memoria dinamica in C++

In alcuni linguaggi di programmazione, ad esempio Java, la gestione della memoria è automatizzata mentre, in C++, la memoria dinamica è gestita dall'utente. In C++ tutto è più complesso, ma basta un po' di allenamento e scoprirete che vi renderà l'apprendimento di altri linguaggi Object-Oriented una passeggiata.

Gli operatori new e new[]

pointer = new type
pointer = new type [number_of_elements]

La prima espressione (new)è usata per allocare in memoria un singolo elemento di un tipo. La seconda espressione (new[]) è usata per assegnare un blocco (array) di elementi del tipo specificato.
Per esempio:
int * bobby;
bobby = new int [5];
In questo caso il sistema assegna dinamicamente spazio per cinque elementi di tipo intero e ritorna un puntatore al primo elemento della sequenza, assegnato a "bobby".  Inoltre "bobby" ora punta a un blocco di memoria con spazio per cinque elementi di tipo intero.

Potete accedere al primo puntato da bobby con l'espressione bobby[0] o con *bobby. Entrambe le espressioni sono equivalenti. Il secondo elemento puntato da bobby è accessibile con bobby[1] o con *(bobby + 1) ecc...


Gli operatori delete e delete[]

Quando un dato allocato non è più necessario è doveroso deallocare la memoria per renderla accessibile nuovamente. Questa operazione può essere eseguita richiamando la funzione delete.
delete pointer;
delete [] pointer;
La prima espressione (delete)viene usata per deallocare un singolo elemento mentre la seconda espressione (delete[]) per deallocare un array.
NB: Il valore passato alla delete deve essere stato prima allocato con l'operatore new altrimenti la delete non ha effetto.

#include <iostream>
using namespace std;

int main ()
{
  int i,n;
  int * p;
  cout << "How many numbers would you like to type? ";
  cin >> i;
  p= new (nothrow) int[i];
  if (p == 0)
    cout << "Error: memory could not be allocated";
  else
  {
    for (n=0; n<i; n++)
    {
      cout << "Enter number: ";
      cin >> p[n];
    }
    cout << "You have entered: ";
    for (n=0; n<i; n++)
      cout << p[n] << ", ";
    delete[] p;
  }
  return 0;
}
 

nothrow: viene usato per controllare se l'accocazione fallisce, ritorna un null pointer o termina il programma.
E' buona pratica controllare sempre se la se memoria è stata allocata nel modo corretto.
Se usate il metodo nothrow potete sempre controllare il valore di ritorno del puntatore.

Commenti