Mi spiegate come vengono gestite le variabili nella memoria?

di il
4 risposte

Mi spiegate come vengono gestite le variabili nella memoria?

Ho sempre immaginato che dichiarando una variabile
var num=1
questa venisse memorizzata nella memoria come una coppia chiave(num) -> valore(1) (quasi come un array).

Tuttavia in praticamente tutti i linguaggi di programmazione con cui ho avuto a che fare, è possibilissimo creare un loop del genere

for (i=0; i<10; i++)
{var num=1}

Quindi creo 10 variabili aventi il nome num.

Si potrebbe immaginare che ad ogni ciclo la variabile del precedente ciclo venga cancellata e riallocata (garbage collected) dato che in questo semplice esempio non ci sono ulteriori referenze alla stessa.
Ma ci sono tuttavia casi più complessi che mi son saltati all'occhio utilizzando l'API di google maps, e nello specifico nell'inizializzazione di molteplici "marker" (che per inciso sarebbero quei puntatori arancioni che indicano un punto preciso della mappa)

Per farla breve questo è il codice
 for( i = 0; i < markers.length; i++ ) 
	{
        var position = new google.maps.LatLng(markers[i][1], markers[i][2]);
        bounds.extend(position);
        marker = new google.maps.Marker({
            position: position,
            map: map,
            title: markers[i][0]
        });
        
        // Aggiungo una infoWindow per ciascun marker 
        google.maps.event.addListener(marker, 'click', (function(marker, i) {
            return function() {
                infoWindow.setContent(infoWindowContent[i][0]);
                infoWindow.open(map, marker);
            }
        })(marker, i));
    }
A differenza che nel primo esempio, questa volta le variabili create nel loop sono referenziate anche nelle fasi successive. Nello specifico il marker è visualizzato a schermo ed è possibile interagirvici (tramite click). Appare quindi chiaro che il marker è un'entità ben definita che deve avere per forza di cose un'allocazione all'interno della memoria.
Ma a questo punto come fa il sistema a distinguere i diversi marker che si sono creati dal momento in cui essi hanno uno stesso nome?

Se al di fuori del loop mi permettessi di scrivere
var num=0;
var num=0;
avrei ovviamente un errore di compilazione, com'è che invece nei loop questo viene bypassato?

4 Risposte

  • Re: Mi spiegate come vengono gestite le variabili nella memoria?

    Qui le cose sono un po' più complicate. Io non ho mai usato quelle api, però credo che ad ogni ciclo si crei un oggetto marker che poi viene aggiunto subito al DOM, per cui al ciclo successivo può anche essere sovrascritto.

    Comunque la memorizzazione delle variabili in memoria non avviene esattamente come pensi tu. A basso livello, per ogni variabile viene memorizzata una coppia nome->indirizzo in una tabella creata dal compilatore o interprete (quella che nel c si chiama tabella dei simboli). Al momento dell'inizializzazione della variabile, viene letto l'indirizzo e memorizzato il valore in quella locazione della ram.

    Se 2 nomi sono uguali e hanno la stessa visibilità, il secondo sovrascrive sempre il primo, a meno che non si adottino delle specie di "prefissi" detti namespace, che però non ci sono in tutti i linguaggi.

    ciao
  • Re: Mi spiegate come vengono gestite le variabili nella memoria?

    Lo spazio di memoria delle variabili finite(intendo variabili di dimensione non modificabile in runtime) viene allocato a tempo di compilazione. In C ad esempio con la malloc() allochi memoria dinamicamente in una zona della ram chiamata heap. Comunque essendo che queste variabili "finite" vengono allocate a tempo di compilazione, penso proprio che la dichiarazione di una variabile all'interno di un ciclo for venga anch'essa passata una sola volta. A mio parere quindi ad ogni ciclo dai un valore diverso alla stessa variabile!
  • Re: Mi spiegate come vengono gestite le variabili nella memoria?

    Le variabili locali, ovvero le variabili che vengono dichiarate all'interno di una funzione, risiedono sullo stack; nel momento in cui si entra nella funzione il puntatore allo stack viene fatto avanzare, nel momento in cui si esce il puntatore dello stack viene riportato alla posizione che aveva all'entrata nella funzione.
    Con la variabile dichiarata all'interno del ciclo for deve essere lo stesso procedimento (ma non ne sono sicuro in quanto potrebbe dipendere dal linguaggio e dall'implementazione).
    Potrebbe sembrarti che la variabile all'interno del for sia uguale (sia come indirizzo che come valore) per diverse passate del tuo ciclo: questo potrebbe essere dovuto al fatto che teoricamente ogni volta dovrebbe ritrovarsi sulla stessa posizione sullo stack.
  • Re: Mi spiegate come vengono gestite le variabili nella memoria?

    Le variabili vengono memorizzate in memoria ad un indirizzo specifico. Ogni nome variabile è associato ad un indirizzo di memoria quindi quando tu scrivi:
    var numero = 3
    il compilatore riserva uno spazio in ram per la variabile e lo associa al nome. Qualsiasi ulteriore riferimento alla variabile sovrascrive la stessa zona di memoria quindi:
    
    for (i=0; i < 10; i++ )
        numero = i;
    
    non fà altro che assegnare alla variabile numero valori diversi sovrascrivendo il valore precedente ed alla fine del loop la variabile avrà valore 9. Questo è quanto avviene per le variabili cosidette "statiche" ed "automatiche".Il loro indirizzo di memoria viene calcolato a compile-time cioè quando il programma viene compilato (o linkato, dipende dal linguaggio) e questo indirizzo non cambia mai nel corso del programma.
    Diverso il caso di memoria allocata dinamicamente. Un programma potrebbe avere bisogno di molta ram nel corso della esecuzione oppure di pochissima ram, dipende dalla interazione dell'utente. sarebbe uno preco allocare 100 megabytes di ram in modo statico per poi accorgersi di avere bisogno di un solo megabytes. la allocazione dinamica della memoria serve a questo: quando ne ho bisogno la richiedo al sistema operativo, quando ho finito la rilascio. In C/C++ questo si ottiene con la funzione 'malloc' mentre in altri linguaggi come javascript con 'new'
    Quindi quando scrivo in C++:
    
    int* numero = new[int];
    
    il compilatore non sà a quale indirizzo sarà allocata la variabile. solo nel momento della esecuzione del programma il sistema cercherà un blocco di memoria libero e lo allocherà per il programma. se lo trova restituisce l'indirizzo di memoria assegnato che viene memeorizzato dal programma come un puntatore a memoria in modo da poter far riferimento alla variabile. questo però implica che nè il compilatore nè il sistema operativo sanno a quale nome variabile io abbia assegnato l'indirizzo e se chiedo un altro blocco di memoria il sistema lo alloca. quindi un ciclo come questo:
    
    for (i=0; i < 10; i++ )
        int* numero = new [int];
    
    provoca l'allocazione di dieci blocchi di memoria distinti. Il problema è che i dieci indirizzi di memoria restituiti dal sistema operativo non sono stati memorizzati: solo l'ultimo è stato scritto sul puntatore 'numero' quindi i primi nove sono inutilizzabili dal momento che il programma non li conosce. peggio, non avendo l'indirizzo allocato non potrò liberare la memoria quando ho finito: questo è il tristemente famoso 'memory leak' tipico del C/C++. non può accadere con linguaggi come java e javascript che hanno la garbage collection perchè la memoria allocata dinamicamente è gestita dalla JVM. In C/C++ invece è responsabilità del programmatore liberare la memroia allocata
Devi accedere o registrarti per scrivere nel forum
4 risposte