Differenza tra allocazione di memoria statica e allocazione di memoria dinamica


Risposte:


91

Esistono tre tipi di allocazione: statica, automatica e dinamica.

Allocazione statica significa che la memoria per le variabili viene allocata all'avvio del programma. La dimensione viene fissata quando viene creato il programma. Si applica a variabili globali, variabili di ambito di file e variabili qualificate con staticfunzioni interne definite.

L'allocazione automatica della memoria si verifica per le variabili (non statiche) definite all'interno delle funzioni e di solito è memorizzata nello stack (sebbene lo standard C non imponga l'uso di uno stack). Non è necessario riservare memoria aggiuntiva utilizzandoli, ma d'altra parte, si ha anche un controllo limitato sulla durata di questa memoria. Ad esempio: le variabili automatiche in una funzione sono presenti solo fino al termine della funzione.

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

L'allocazione dinamica della memoria è leggermente diversa. Ora puoi controllare la dimensione esatta e la durata di queste posizioni di memoria. Se non lo liberi, incapperai in perdite di memoria, che potrebbero causare l'arresto anomalo dell'applicazione, poiché a 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 in alto, la memoria allocata è ancora valida e accessibile, anche se la funzione è terminata. Quando hai finito con la memoria, devi liberarla:

free(mem);

2
Sicuro di avere il controllo sulla durata delle variabili ... sei tu a decidere l'ambito, giusto?
Luchian Grigore

Certo, ma non è quello che intendevo. Non è possibile estendere la durata delle variabili per sopravvivere al suo ambito. Ma forse dovrei chiarirlo nella mia risposta. Grazie
Constantinius

5
-1 Questa risposta è sbagliata. Confondi le variabili statiche e quelle automatiche .
brice

2
La tua frase dice: " Allocazione statica significa che la memoria per le tue variabili viene allocata automaticamente " Questo è sbagliato . Dai un'occhiata a ciò che la pagina di manuale per la libc di GNU ha da dire al riguardo.
brice

1
@EliBendersky Ora è riformulato. Controlla se è corretto ora.
Suraj Jain

116

Questa è una domanda di intervista standard:

Allocazione dinamica della memoria

È la memoria allocata in fase di esecuzione utilizzando calloc(), malloc()e gli amici. A volte viene anche definita memoria "heap", sebbene non abbia nulla a che fare con la struttura dati dell'heap ref .

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

La memoria heap è persistente finché non free()viene chiamata. In altre parole, controlli la durata della variabile.

Allocazione automatica della memoria

Questa è quella che è comunemente nota come memoria "stack" e viene allocata quando si entra in un nuovo ambito (di solito quando una nuova funzione viene inserita nello stack di chiamate). Una volta usciti dall'ambito, i valori degli indirizzi di memoria automatici non sono definiti ed è un errore accedervi .

int a = 43;

Nota che l'ambito non significa necessariamente funzione. Gli ambiti possono essere nidificati all'interno di una funzione e la variabile sarà nell'ambito solo all'interno del blocco in cui è stata dichiarata. Notare anche che dove questa memoria è allocata non è specificato. (Su un sistema sano sarà in pila o si registrerà per l'ottimizzazione)

Allocazione statica della memoria

Viene allocato in fase di compilazione * e la durata di una variabile nella memoria statica è la durata del programma .

In C, la memoria statica può essere allocata utilizzando la staticparola chiave. Lo scopo è solo l'unità di compilazione.

Le cose diventano più interessanti quando externsi considera la parola chiave . Quando una externvariabile viene definita, il compilatore le alloca la memoria. Quando externviene dichiarata una variabile , il compilatore richiede che la variabile sia definita altrove. La mancata dichiarazione / definizione di externvariabili causerà problemi di collegamento, mentre la mancata dichiarazione / definizione di staticvariabili causerà 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, externe staticsono due classi separate di variabili in C.

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

* Note sull'allocazione della memoria statica

È un po 'confuso dire che la memoria statica viene allocata in fase di compilazione, soprattutto se iniziamo a considerare che la macchina di compilazione e la macchina host potrebbero non essere la stessa o potrebbero non essere nemmeno sulla stessa architettura.

Potrebbe essere meglio pensare che l'allocazione della memoria statica sia gestita dal compilatore piuttosto che allocata in fase di compilazione .

Ad esempio il compilatore può creare una grande datasezione nel binario compilato e quando il programma viene caricato in memoria, l'indirizzo all'interno deldatasegmento del programma verrà utilizzato come posizione della memoria allocata. Questo ha il marcato svantaggio di rendere il binario compilato molto grande se utilizza molta memoria statica. È possibile scrivere un binario multi-gigabyte generato da meno di mezza dozzina di righe di codice. Un'altra opzione è che il compilatore inserisca 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 e al sistema operativo di destinazione. In pratica, i compilatori moderni utilizzano l'euristica per decidere quale di queste opzioni utilizzare. Puoi provarlo tu stesso scrivendo un piccolo programma C che alloca un ampio array statico di elementi da 10k, 1m, 10m, 100m, 1G o 10G. Per molti compilatori, la dimensione binaria continuerà a crescere linearmente con la dimensione dell'array e oltre un certo punto,

Registra la memoria

L'ultima classe di memoria sono le variabili "registro". Come previsto, le variabili di registro dovrebbero essere allocate sul registro di una CPU, ma la decisione è in realtà lasciata al compilatore. Non è possibile trasformare una variabile di registro in un riferimento utilizzando address-of.

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

La maggior parte dei compilatori moderni è più intelligente di te nello scegliere le variabili da inserire nei registri :)

Riferimenti:


3
Nota: suggerirei int * a = malloc(sizeof(*a));invece di evitare di ripetere il tipo di file a. Questo rende le cose molto più facili se mai il tipo di amodifiche.
Shahbaz

1
In realtà si chiama heap ma non ha nulla a che fare con la struttura dei dati dell'heap. Heap in questo caso significa un posto disordinato
dinamico

2
"Allocazione statica della memoria ... viene allocata in fase di compilazione" Vuoi dire che la dimensione dell'allocazione viene determinata in fase di compilazione? La messa da parte della memoria non avverrebbe solo in fase di esecuzione?
lf215

2

Allocazione di memoria statica: il compilatore alloca lo spazio di memoria richiesto per una variabile dichiarata.Utilizzando l'indirizzo dell'operatore, si ottiene l'indirizzo riservato e questo indirizzo può essere assegnato a una variabile puntatore.Poiché la maggior parte della variabile dichiarata ha memoria statica, questa Il modo di assegnare il valore del puntatore a una variabile del puntatore è noto come allocazione della memoria statica. la memoria viene assegnata durante il tempo di compilazione.

Allocazione dinamica della memoria: utilizza funzioni come malloc () o calloc () per ottenere la memoria dinamicamente.Se queste funzioni vengono utilizzate per ottenere la memoria dinamicamente ei valori restituiti da queste funzioni sono assegnati a variabili puntatore, tali assegnazioni sono note come memoria dinamica Allocation.memory viene assegnato durante il runtime.


2

Allocazione statica della memoria:

  • Le variabili vengono allocate in modo permanente
  • L'assegnazione viene eseguita prima dell'esecuzione del programma
  • Utilizza la struttura dati chiamata stack per implementare l'allocazione statica
  • Meno efficiente
  • Non è possibile riutilizzare la memoria

Allocazione dinamica della memoria:

  • Le variabili vengono assegnate solo se l'unità di programma diventa attiva
  • L'allocazione viene eseguita durante l' esecuzione del programma
  • Utilizza la struttura dati chiamata heap per implementare l'allocazione dinamica
  • Più efficiente
  • C'è la riutilizzabilità della memoria . La memoria può essere liberata quando non è necessaria

1
"Static Memory Allocation [...] Utilizza la struttura dati chiamata stack per implementare l'allocazione statica" No , è sbagliato e fuorviante. si prega di consultare il mio post per la differenza tra allocazione automatica e statica. La memoria statica può utilizzare lo stack. Ciò dipende fortemente dall'implementazione e possono essere utilizzate più strategie per la stessa implementazione. Non sono sicuro nemmeno di cosa intendi per "meno efficiente". @Trieu Toan, hai cambiato il significato di questa risposta con una brutta modifica.
brice

1

Differenza tra STATIC MEMORIA ALLOCAZIONE & DYNAMIC MEMORY ALLOCAZIONE

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

Nessuna allocazione di memoria o azioni di deallocazione vengono eseguite durante l'esecuzione.
Le associazioni di memoria vengono stabilite e distrutte durante l'esecuzione.

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

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

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

Esecuzione più veloce rispetto a Dynamic.
Esecuzione più lenta rispetto a quella statica.

Più spazio di memoria richiesto.
Meno spazio di memoria richiesto.


1
l'allocazione della memoria statica viene allocata sullo Stack mentre l'allocazione della memoria dinamica viene allocata sull'heap
Usman Kurd

@UsmanKurd Questo è generalmente errato per quanto riguarda la memoria statica. Vedi la mia risposta.
brice

0

L'allocazione della memoria statica viene assegnata alla memoria prima dell'esecuzione del programma pf durante la compilazione. La posizione di memoria dinamica è la memoria allocata durante l'esecuzione del programma in fase di esecuzione.


-1

Allocazione statica della memoria. La memoria allocata sarà nello stack.

int a[10];

Allocazione dinamica della memoria. La memoria allocata sarà nell'heap.

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

e quest'ultimo dovrebbe essere libero d poiché non c'è Garbage Collector (GC) in C.

free(a);
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.