2011-02-27 13 views
12

Perché il codice seguente emette sempre la stessa posizione di memoria?Variabili locali a ciclo continuo in C

int x; 
for (x = 0; x < 10; x++) { 
    int y = 10; 
    printf("%p\n", &y); 
} 

Ho pensato che la posizione della memoria dovrebbe cambiare ogni volta che viene eseguito il ciclo, la variabile è nuova.

risposta

18

Sì, hai assolutamente ragione che la posizione di memoria potrebbe cambiare. Ma non deve :) In ogni iterazione la vecchia variabile viene "distrutta" e una nuova viene "creata" nello stesso posto. Sebbene qualsiasi compilatore decente ottimizzi le "azioni" non necessarie

+0

Oh, va bene, grazie. Ho semplificato eccessivamente questa domanda, in quanto sto provando a creare una lista collegata, e creo un nuovo nodo in un ciclo for, e non voglio che il nodo successivo sovrascriva il nodo dall'iterazione precedente, ma è quello che sta facendo Pubblicherò una nuova domanda, una volta che posso produrre uno snippet di codice che può essere facilmente analizzato. –

+4

se si desidera che le strutture di dati persistenti debbano essere create su "heap" anziché "stack". Usa 'malloc' ecc per questo. – Alnitak

+1

@amandeepGrewal: dovresti creare le variabili sull'heap (con malloc) per ottenere il comportamento desiderato –

5

Sì, la variabile è nuova ogni volta, ma alla fine del blocco vengono rilasciate nuovamente tutte le nuove variabili sullo stack.

Quindi la prossima volta attorno al puntatore dello stack è esattamente dove si trovava. NB: questo comportamento è comune, ma lo standard non è garantito.

0

Le regole di ambito per le variabili descrivono solo l'ambito in cui si ha il diritto di accedere a una variabile locale: dalla definizione alla fine del blocco.

Questa regola non dice nulla del momento in cui lo spazio è riservato. Una strategia comune è quella di riservare spazio per tutte le variabili che saranno necessarie per un'invocazione di una funzione contemporaneamente, all'inizio della funzione.

Quindi quando l'esecuzione incrocia una definizione di una variabile, di solito non si deve fare nulla in particolare, non una singola istruzione. D'altra parte questo lascia il valore di quella variabile a tutto ciò che è stato trovato lì in precedenza. Quindi l'importanza dell'inizializzazione in uno stato noto, come hai fatto nel tuo esempio con lo = 10.

2

È un'ottimizzazione del compilatore. Poiché la variabile locale sta uscendo dall'ambito e una variabile dello stesso tipo esatto sta per essere creata, sta riutilizzando l'indirizzo di memoria. È importante notare che questa è ancora una variabile "fresca" o "nuova" per quanto riguarda il tuo programma.

Confronta i seguenti frammenti di codice e l'output:

for (i = 0; i < 3; i++) { 
    int n = 0; 
    printf("%p %d\n", (void *)&n, n++); 
} 
 
0x7fff56108568 0 
0x7fff56108568 0 
0x7fff56108568 0 
for (i = 0; i < 3; i++) { 
    static int n = 0; 
    printf("%p %d\n", (void *)&n, n++); 
} 
 
0x6008f8 0 
0x6008f8 1 
0x6008f8 2 
Problemi correlati