Domanda

Vorrei sapere qual è la differenza tra l'allocazione della memoria statica e l'allocazione della memoria dinamica?

Potresti spiegarlo con qualche esempio?

È stato utile?

Soluzione

Esistono tre tipi di allocazione: statico, automatico e dinamico.

Allocazione statica significa che la memoria per le tue variabili viene allocata all'avvio del programma. La dimensione è fissata quando viene creato il programma. Si applica alle variabili globali, alle variabili dell'ambito del file e alle variabili qualificate con static definito all'interno delle funzioni.

Allocazione della memoria automatica si verifica per le variabili (non statiche) definite all'interno delle funzioni e di solito è memorizzata su pila (Sebbene lo standard C non imponga che venga utilizzato uno stack). Non è necessario prenotare la memoria extra usandoli, ma d'altra parte, hai anche un controllo limitato per tutta la vita di questa memoria. Ad esempio: le variabili automatiche in una funzione sono lì solo fino alla fine della funzione.

void func() {
    int i; /* `i` only exists during `func` */
}

Allocazione di memoria dinamica è un po 'diverso. Ora controlli le dimensioni esatte e la durata di queste posizioni di memoria. Se non lo libererai, ti imbatterai in perdite di memoria, il che potrebbe far sì che la tua applicazione si arrestasse, dal momento che in un certo punto, il sistema non può allocare più memoria.

int* func() {
    int* mem = malloc(1024);
    return mem;
}

int* mem = func(); /* still accessible */

Nell'esempio superiore, la memoria allocata è ancora valida e accessibile, anche se la funzione è terminata. Quando hai finito con la memoria, devi liberarlo:

free(mem);

Altri suggerimenti

Questa è una domanda di intervista standard:

Allocazione di memoria dinamica

È la memoria assegnata in fase di esecuzione utilizzando calloc(), malloc() e amici. A volte viene anche indicato come memoria di "heap", sebbene non abbia nulla a che fare con la struttura dei dati HEAP rif.

int * a = malloc(sizeof(int));

La memoria dell'heap è persistente fino a free() è chiamato. In altre parole, controlli la vita della variabile.

Allocazione della memoria automatica

Questo è ciò che è comunemente noto come memoria di "stack" ed è assegnato quando si inserisce un nuovo ambito (di solito quando una nuova funzione viene spinta sullo stack di chiamata). Una volta usciti dall'ambito, i valori degli indirizzi di memoria automatica sono indefiniti ed è un Errore per accedervi.

int a = 43;

Si noti che l'ambito non significa necessariamente una funzione. Gli ambiti possono nidificare all'interno di una funzione e la variabile sarà in-scenica solo all'interno del blocco in cui è stato dichiarato. Si noti inoltre che non è specificato laddove questa memoria. (Su a sano sistema sarà sullo stack o registri per l'ottimizzazione)

Allocazione della memoria statica

È assegnato al momento della compilazione*, e la vita di una variabile nella memoria statica è il Vita del programma.

In C, la memoria statica può essere assegnata usando il static parola chiave. L'ambito è solo l'unità di compilazione.

Le cose diventano più interessanti quando il extern La parola chiave viene considerata. Quando un extern la variabile è definito Il compilatore assegna la memoria per questo. Quando un extern la variabile è dichiarato, il compilatore richiede che la variabile sia definito altrove. Mancata dichiarazione/definizione extern Le variabili causano problemi di collegamento, mentre l'incapacità di dichiarare/definire static Le variabili causano problemi di compilazione.

Nell'ambito del file, la parola chiave statica è facoltativa (al di fuori di una funzione):

int a = 32;

Ma non nell'ambito della funzione (all'interno di una funzione):

static int a = 32;

Tecnicamente, extern e static sono due classi separate di variabili in C.

extern int a; /* Declaration */
int a; /* Definition */

*Note sull'allocazione della memoria statica

È in qualche modo confuso affermare che la memoria statica è assegnata al momento della compilazione, soprattutto se iniziamo a considerare che la macchina di compilazione e la macchina host potrebbero non essere uguali o non potrebbero nemmeno essere sulla stessa architettura.

Potrebbe essere meglio pensare che l'allocazione della memoria statica sia gestita dal compilatore piuttosto che Assegnato al momento della compilazione.

Ad esempio, il compilatore può creare un grande data sezione nella binaria compilata e quando il programma viene caricato in memoria, l'indirizzo all'interno del data Il segmento del programma verrà utilizzato come posizione della memoria assegnata. Ciò ha lo svantaggio marcato di rendere il binario compilato molto grande se usa molta memoria statica. È possibile scrivere un binario multi-gigabyte generato da meno di una mezza dozzina di righe di codice. Un'altra opzione è che il compilatore inietta il codice di inizializzazione che allocherà la memoria in qualche altro modo prima che il programma venga eseguito. Questo codice varierà in base alla piattaforma di destinazione e al sistema operativo. In pratica, i compilatori moderni usano l'euristica per decidere quale di queste opzioni utilizzare. Puoi provarlo da solo scrivendo un piccolo programma C che assegna un grande array statico di articoli 10K, 1M, 10m, 100m, 1G o 10G. Per molti compilatori, le dimensioni binarie continueranno a crescere linearmente con le dimensioni dell'array e oltre un certo punto, si ridurrà di nuovo poiché il compilatore utilizza un'altra strategia di allocazione.

Registra la memoria

L'ultima classe di memoria sono le variabili "Registra". Come previsto, le variabili di registro devono essere assegnate su un registro della CPU, ma la decisione è effettivamente lasciata al compilatore. Non è possibile trasformare una variabile di registro in un riferimento utilizzando l'indirizzo di.

register int meaning = 42;
printf("%p\n",&meaning); /* this is wrong and will fail at compile time. */

La maggior parte dei compilatori moderni sono più intelligenti di te nel raccogliere quali variabili dovrebbero essere messe nei registri :)

Riferimenti:

Allocazione della memoria statica: Il compilatore alloca lo spazio di memoria richiesto per una variabile dichiarata. By usando l'indirizzo dell'operatore, si ottiene l'indirizzo riservato e questo indirizzo può essere assegnato a una variabile puntatore. Dal momento Il valore a una variabile puntatore è noto come allocazione della memoria statica. La memoria viene assegnata durante il tempo di compilazione.

Allocazione della memoria dinamica: Utilizza funzioni come Malloc () o Calloc () per ottenere la memoria in modo dinamico. Se queste funzioni vengono utilizzate per ottenere la memoria in modo dinamico e i valori restituiti da queste funzioni vengono assunti alle variabili del punta presentato durante il tempo di esecuzione.

Allocazione della memoria statica:

  • Le variabili vengono assegnate permanentemente
  • L'allocazione è fatta prima Esecuzione del programma
  • Utilizza la struttura dei dati chiamata pila per l'implementazione di allocazione statica
  • Meno efficiente
  • C'è nessuna riusabilità della memoria

Allocazione della memoria dinamica:

  • Le variabili vengono assegnate solo Se l'unità del programma diventa attiva
  • L'allocazione è fatta in occasione Esecuzione del programma
  • Utilizza la struttura dei dati chiamata mucchio Per l'implementazione dell'allocazione dinamica
  • Più efficiente
  • C'è riusabilità della memoria . La memoria può essere liberata quando non è necessario

Differenza tra Allocazione della memoria statica & Allocazione di memoria dinamica

La memoria viene assegnata prima dell'inizio dell'esecuzione del programma (durante la compilation).
La memoria viene assegnata durante l'esecuzione del programma.

Non vengono eseguite azioni di allocazione della memoria o deallocalizzazione durante l'esecuzione.
I legami di memoria vengono stabiliti e distrutti durante l'esecuzione.

Le variabili rimangono permanentemente allocate.
Assegnato solo quando l'unità di programma è attiva.

Implementato utilizzando stack e cumuli.
Implementato utilizzando segmenti di dati.

Il puntatore è necessario per l'accesso alle variabili.
Non c'è bisogno di puntatori allocati dinamicamente.

Esecuzione più veloce che dinamica.
Esecuzione più lenta di statica.

È richiesto più spazio di memoria.
Meno spazio di memoria richiesto.

L'allocazione della memoria statica viene assegnata la memoria prima del programma di esecuzione PF durante il tempo di compilazione. La memoria dinamica Alocation è una memoria alocata durante l'esecuzione del programma in fase di esecuzione.

Allocazione della memoria statica. La memoria assegnata sarà in stack.

int a[10];

Allocazione di memoria dinamica. La memoria assegnata sarà in heap.

int *a = malloc(sizeof(int) * 10);

e quest'ultimo dovrebbe esserlo gratuitoD poiché non esiste un collezionista di immondizia (GC) in C.

free(a);
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top