libri-javascript-python

In questa lezione parleremo della funzione malloc in C e dell’allocazione dinamica della memoria.

Come abbiamo già studiato nelle lezioni precedenti, i puntatori consentono di gestire aree di memoria in maniera diretta. Non consentono però di espandere o costruire a runtime l’area di memoria destinata all’utilizzo dei dati.

A runtime ricordiamo che vuol dire durante l’esecuzione.

Cioè un vettore, ad esempio, deve essere dimensionato all’inizio del programma e in fase di runtime la sua dimensione fisica non può variare.

Però spesso accade di voler dimensionare le strutture dati durante l’esecuzione del programma.

In genere, se ad esempio vogliamo includere il caso in cui si voglia variare la dimensione dell’array, in base ad un valore espresso dall’utente, la soluzione più ovvia ma anche più ‘rozza’ che ci viene in mente è quella di sovradimensionare l’array con uno spreco inevitabile di memoria.

Invece, allocare la quantità di memoria di volta in volta necessaria e de-allocarla quando non serve più, produce chiaramente programmi più efficienti.

Per fare ciò ci vengono in auto le funzioni malloc, calloc, free e realloc in C, che servono a creare e gestire oggetti dinamici.


Uso della funzione malloc in C

La funzione malloc in C serve dunque ad allocare un’area di memoria durante l’esecuzione del programma.

La sintassi è questa:

void *malloc(size_t)

con size_t indichiamo la quantità di memoria (numero di byte) da allocare.

La funzione malloc ritorna un puntatore, di tipo void, al primo byte dell’area allocata.

Ricordiamo che, secondo lo standard, un puntatore di tipo void può essere assegnato a qualsiasi tipo di puntatore.

Per evitare possibili problemi con i compilatori, è consigliabile effettuare un’operazione di cast per adeguare il valore di ritorno al tipo di puntatore richiesto.

Facciamo quindi un semplice esempio a scopo didattico di utilizzo di malloc in C:

#include <stdio.h>
#include <stdlib.h>

int main() {
	int *p; //dichiariamo il puntatore a variabile intera

	//allocazione dinamica adatta a contenere un numero intero
	p=(int *) malloc(sizeof(int));
	
	*p=50; 
	
	printf("*p vale %d\n", *p);

   return 0;
}

In questo esempio si dichiara il puntatore come variabile intera e poi, utilizzando la funzione malloc, il programma gli permette di allocare un’area di memoria sufficientemente grande da poter contenere un numero intero.

Dopo aver effettuato l’allocazione assegniamo all’area di memoria puntata da p un valore, nell’esempio assegno il valore 50.

Infine stampo il valore assegnato per verificare che la locazione di memoria contiene effettivamente il valore assegnato.

Se l’allocazione non avviene correttamente il puntatore assume valore NULL.

È consigliabile dunque effettuare un test sul contenuto del puntatore, in modo tale che, se l’allocazione non avviene correttamente (per esempio se non abbiamo sufficiente spazio di memoria), si ha ad esempio un messaggio d’errore o la fuoriuscita dal programma.

Quindi basterà fare un controllo del tipo:

       .....
          if (p==NULL)
		printf("non è possibile allocare");
       .....

Alcuni link utili

Media per riga e per colonna

Somma elementi diagonale principale di una matrice

Come sommare gli elementi della cornice esterna

Come sommare due matrici

Sommare dei numeri di una matrice

Matrice trasposta

Prodotto tra matrici

Programma sui triangoli in C

Array con numeri random

Quick sort in C

Merge sort in C

Insertion Sort in C