È necessario utilizzare memoria dinamica quando:
- Non è possibile determinare la quantità massima di memoria da utilizzare in fase di compilazione;
- Si desidera assegnare uno molto grande oggetto;
- Si desidera creare strutture di dati (contenitori) senza una dimensione superiore fissa;
Non sempre sapere quanta memoria è necessario mettere da parte al momento della compilazione. Immagina di elaborare un file di dati (una serie temporale di temperature, ad esempio), in cui il numero di record nel file non è fisso. Potresti avere solo 10 record o fino a 100000. Se vuoi leggere tutti i dati in memoria per elaborarli, non sai quanta memoria allocare finché non leggi il file. Se il file è strutturato in modo che il primo valore è il numero di record, si potrebbe fare qualcosa di simile:
size_t recs = 0;
double *temps = NULL;
FILE *fp = fopen (filename, "r");
if (fp)
{
if (fscanf(fp, "%zu", &recs) == 1)
{
temps = malloc(sizeof *temps * recs);
if (temps)
{
// read contents of file into temps
}
}
}
A volte è necessario allocare un oggetto di grandi dimensioni molto, qualcosa come
int ginormous[1000][1000][1000];
Assumendo un numero intero a 4 byte, questo array richiede 4 GB. Sfortunatamente, i frame di stack (dove le variabili locali sono mantenute sulla maggior parte delle architetture) tendono ad essere molto più piccoli di così, quindi provare a allocare così tanta memoria può portare ad un errore di run-time (e tipicamente lo fa). La memoria dinamica (pseudonimo mucchio) è tipicamente molto maggiore della pila, tanto meno qualsiasi stack frame. così per qualcosa che antipatici avresti bisogno di scrivere qualcosa di simile
int (*ginormous)[1000][1000] = malloc(sizeof *ginormous * 1000);
E 'ancora possibile per una richiesta del genere a fallire; se il tuo heap è sufficientemente frazionato, potresti non avere un singolo blocco contiguo abbastanza grande da soddisfare la richiesta.Se necessario, potresti eseguire un'allocazione frammentaria; righe non saranno necessariamente essere adiacenti in memoria, ma è più probabile che sarete in grado di afferrare tutta la memoria è necessario:
int ***ginormous = malloc(sizeof *ginormous * 1000);
if (ginormous)
{
for (size_t i = 0; i < 1000; i++)
{
ginormous[i] = malloc(sizeof *ginormous[i] * 1000);
if (ginormous[i])
{
ginormous[i][j] = malloc (sizeof *ginormous[i][j] * 1000);
if (ginormous[i][j])
{
// initialize ginormous[i][j][k]
}
}
}
}
E, infine, la memoria dinamica consente di creare contenitori che possono crescere e ridursi come aggiungi o rimuovi dati, come elenchi, alberi, code, ecc. Potresti persino creare il tuo vero tipo di dati "stringa" che può crescere man mano che aggiungi caratteri (simile al tipo string
in C++).
Provare a scrivere un programma che chiede all'utente un numero (ad esempio, il numero di studenti nella classe), quindi quel numero di volte chiede loro un nome per compilare un elenco di studenti nella classe (e quindi ordina i nomi in ordine alfabetico e li scrive in un file, o qualcosa del genere). In quale array di dimensioni vengono archiviati i nomi? – Michelle
possibile duplicato di [Quando dovrei usare malloc in C e quando no?] (Http://stackoverflow.com/questions/1963780/when-should-i-use-malloc-in-c-and-when -dont-i) – koopajah
Informazioni sulla trasmissione del valore restituito di malloc si consiglia di leggere questo http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc – koopajah