Riallocazione di memoria

L'uso congiunto delle funzioni malloc e free consente di aumentare la zona di memoria associata ad un vettore (dinamico). Supponiamo infatti di aver allocato un vettore di cento elementi p, e ci accorgiamo che questi cento elementi non bastano. Quello che possiamo fare è:

  1. creiamo un vettore di duecento elementi
  2. copiamo i cento elementi del vettore nella nuova zona di memoria
  3. liberiamo la vecchia zona di memoria puntata da p
  4. assegnamo a p l'indirizzo della nuova zona di memoria

È facile rendersi conto che questa sequenza di istruzioni ci porta ad avere che p punta a una zona di memoria di duecento elementi, i cui primi cento hanno lo stesso valore dei cento elementi dell'array originario. Abbiamo quindi realizzato l'allungamento dell'array.

In C, è possibile realizzare la stessa cosa usando la funzione realloc. In prima approssimazione, possiamo dire che la funzione fa queste operazioni di nuova allocazione, copia, e rilascio della vecchia zona di memoria. In pratica, la funzione viene sempre usata in questo modo:

  p=realloc(p, numero_byte);

Ossia si passa come prima parametro un puntatore, e si mette il risultato nello stesso puntatore. L'effetto è quello di aver aumentato la dimensione della zona puntata da p.

Il seguente programma realloces.c mostra un esempio di uso di questa funzione. Inizialmente si alloca una zona di cento interi, e quindi sono corrette solo le operazioni su p[0]...p[99], mentre l'uso o assegnazione di p[100], p[101] ecc sono scorrette perchè fuori dalla zona assegnata. Dopo aver fatto la realloc, la zona assegnata è diventata grande abbastanza da contenere duecento interi, per cui ora le operazioni su p[0]...p[199] sono tutte valide.

Per concludere, notiamo come la funzione realloc si può anche chiamare più volte sullo stesso puntatore. Nell'esempio di sotto, nel caso in cui duecento elementi non fossero stati sufficienti, si poteva fare una nuova realloc per allocarne 300, poi ancora una volta per allocarne 400, ecc.

/*
  Alloca un array, e poi lo rialloca.
*/

#include<stdlib.h>

int main() {
  int *p;
  int i;

		/* allocazione iniziale */
  p=malloc(100*sizeof(int));


		/* operazione corretta */
  p[20]=1;
  p[99]=-12;


		/* operazione scorrette: p[112] non e' nella
		zona di memoria riservata dalla malloc */
  p[112]=-32;


		/* riallocazione */
  p=realloc(p, 200*sizeof(int));


		/* ora si puo' usare fino a p[199] */
  p[112]=-32;	/* operazione corretta */


  		/* la parte precedentemente allocata del vettore
		rimane inalterata */
  printf("p[20]=%d p[99]=%d p[112]=%d\n", p[20], p[99], p[112]);

  return 0;
}



Dopo la prima allocazione, la situazione in memoria è la seguente:

Dopo la riallocazione, è stata creata una nuova zona di memoria che può contenere duecento elementi, e i valori della zona di memoria precedente sono stati copiati. La vecchia zona di memoria è anche stata liberata.