Newsgroup: it.comp.programmare
Titolo: l'area della memoria denominata stack è dinamica?

Ciao
l'area della memoria denominata stack è utilizzata per la gestione 
statica o dinamica?
Nel caso di una funzione ricorsiva dove non sappiamo quante iterazioni 
avremo, e considerando l'allocazione nella pila dei cosiddetti record di 
attivazioni relativi ai blocchi delle procedure, mi viene da pensare che 
sia dinamica, come la heap....ma con procedure differenti di allocazione.
www.html.it
 un sito ho letto che è un'area per contenere i dati statici.
ma i dati allocati staticamente non sono le variabili globali,lecostanti 
e le tabelle per il supporto run time?
grazie

 allocazione.
Forse stai confondendo stack con record di attivazione. 
Lo stack è utilizzato dall'intero programma, mentre il record di 
attivazione rappresenta una singola chiamata a funzione.
Che sia ricorsiva o meno, non cambia il discorso. Se f chiama g, ad un 
certo punto avrai 2 record di attivazione: uno per f e uno per g.
Lo stack è fissato a priori e quindi potrebbe finire nel caso in cui f 
chiami g che chiama h che chiama m...e così per un milione di volte.
Certamente bisogna mettersi di impegno per finire lo stack senza chiamate 
ricorsive dirette o indirette (non so neanche dirti se sia umanamente 
possibile).

 chiami g che chiama h che chiama m...e così per un milione di volte.
In effetti l'implementazione tradizionale dei linguaggi non gestiti
normalmente è problematica, perché funge così:
  |SsSsSsSsSsS... ---> crescita dello stack .... .... HhHhhHhHhHhHh|
dove S è la parte allocata allo stack, H è la parte allocata all'heap, e
da sinistra a destra si hanno indirizzi crescenti. Ovviamente, se lo
stack cresce troppo, andrà a "battere la capoccia" contro l'heap... e
non c'è modo di saperlo, perché l'heap essendo allocato alla nostra app
non ha protezione (*). Bang! Lo stack sovrascrive l'heap. Corruzione
della memoria.
Gah.
 - ∞, IIRC.
(*) salvo che la libreria che sta facendo l'allocazione non metta
guardie prima e dopo i dati per accorgersene. libSystem sotto OS X ha la
possibilità di farlo, per dire.

 possibile).
E' invece piuttosto facile. Ecco un esempio di programma in linguaggio C 
(di una sola riga!), che va in crash su qualunque piattaforma che 
conosca. Per funzionare avrebbe bisogno di uno stack di almeno un GB.
int main() { char a[1000000000]; }
In generale, il record di attivazione cresce dello spazio allocato 
automaticamente per i parametri della funzione + di quello allocato 
automaticamente per le variabili locali non statiche.
Se nel programma precedente si sostituisce il numero con 10, il 
programma funziona (e non fa niente) su qualunque piattaforma.
-- 
Carlo Milanesi
http://digilander.libero.it/carlmila

 funziona (e non fa niente) su qualunque piattaforma.
Beh, sarebbe strano non poter dichiarare un array di 10 char :-)
Invece č da notare come in effetti il programmi funzioni se l'array viene 
dichiarato static. 

 cresce dello spazio allocato?
 >
 > Vuoi dire che lo spazio allocato per un record di attivazione è dato
 > dallo spazio necessario ad allocare i suoi parametri più quello > > > 
 > necessario ad allocare le variabili locali non statiche?
Si', ma mi spiego meglio. Intendevo dire: "ogni implementazione puo' 
fare quello che vuole, soprattutto se sono attive delle ottimizzazioni e 
dei vincoli di allineamento dei dati, ma approssimativamente il record 
di attivazione ha una lunghezza pari a qualche byte, diciamo 8, piu' lo 
spazio allocato automaticamente per i parametri della funzione, piu' lo 
spazio allocato automaticamente per le variabili locali non statiche."
Per esempio, consideriamo la seguente funzione:
void f(double a, short b) {
     static long c;
     char* d;
     char e;
     ...
}
Su un sistema a 32 bit, la chiamata a questa funzione dovrebbe allocare 
sullo stack 8 byte fissi, piu' 8 byte per il double "a", piu' 2 byte per 
lo short "b", piu' 4 byte per il puntatore "d", piu' 1 byte per il char 
"e", per un totale di 8+8+2+4+1=23.
La variabile c, essendo static, non occupa spazio di stack.
In realta' compilando senza ottimizzazioni ottengo 28, e con 
ottimizzazioni ottengo 20.
La spiegazione del 28 e' che lo short e il char occupano comunque 4 byte 
per motivi di allinamento.
La spiegazione del 20 e' che nel codice non uso mai le variabili "d" ed 
"e", e quindi sono state eliminate.


 "e", e quindi sono state eliminate.
Come fai a vedere tali valori? 

Noixe ha scritto:

Il seguente programma mostra (in esadecimale) per 4 volte l'indirizzo 
dell'oggetto (di tipo char*) associato alla variabile "d".
Dato che si tratta di 4 attivazioni della stessa variabile, la 
differenza tra due attivazioni consecutive e' proprio la lunghezza del 
record di attivazione.
#include <cstdio>
void f(double a, short b) {
     static long c;
     char* d;
     char e;
     printf("%p\n", &d);
     if (b > 0) f(a, b - 1);
}
int main() {
     f(0.0, 3);


 attivazione.
Ah, ti basi sull'indirizzo di memoria, pensavo, usassi qualche opzione 
particolare.
Il mio compilatore alloca 32 bytes (mingw, porting di g++ su windows)
Come mai non metti %d tra i parametri della printf in modo da avere 
direttamente i valori in base 10?
A cosa serve %p?
Ciao 

> A cosa serve %p?
E' il formattatore dei puntatori.
Pleg