Newsgroup: it.comp.lang.c
Titolo: Array statico e dinamico

Che differenza c'e' tra un array statico ed uno dinamico?
grazie a tutti coloro che mi aiuteranno!
Ciao
--------------------------------
Inviato via 
http://arianna.libero.it/usenet/

 grazie a tutti coloro che mi aiuteranno!
Dunque... tralasciando la terminologia (di cui non te ne può fregare di
meno, nella fase in cui sei), l'array statico è quello del tipo:
int a[100];
Ora a è un array statico. Ha 100 elementi, numerati da 0 a 99.
Problema. Metti il caso che tu abbia:
int b = 5;
int a[b];
Questo non si può fare... La dimensione di un array statico dev'essere
conosciuta dal compilatore. Per questo viene definito "statico".
L'array statico è posizionato nello stack. Di solito lo stack ha dimensioni
limitate (teoricamente ha le dimensioni che tu dici al linker che deve
avere, in pratica si va su architetture moderne da poco (diciamo 1mb con il
Visual C++) a 16 mb...). Il tempo di allocazione di un array nello stack è
nullo. L'array si libererà da solo quando uscirai dal pezzo di codice in cui
è stato definito (scope) (quindi se l'hai definito in una funzione, quando
esci dalla funzione l'array sparisce e la memoria viene liberata).
Adesso ti chiederai... E l'array dinamico? Ti ricordi il problema che non si
poteva risolvere? Beh... Ora lo risolviamo!
(se non sai cosa sono i puntatori, studiateli e poi torna qui).
int b = 5;
int *a = (int*)malloc(b * sizeof(int));
if (a == NULL)
    return;
.
.
.
free(a);
a = NULL;
Ecco... la malloc ci ha allocato un pezzo di memoria in cui ci stanno
comodamente b interi. Nota che la malloc non sa quasi niente di tipi di
variabili e cavolate simili. La malloc alloca X bytes. Noi sappiamo che un
intero occupa sizeof(int) bytes, e quindi chiediamo alla malloc di allocare
b * sizeof(int) bytes.
Ora, tu puoi accedere alla memoria in due maniere:
a[0] = 5; /* Oppure *a = 5; o *(a + 0) = 5 */
a[1] = 6; /* Oppure *(a + 1) = 6 */
la malloc alloca la memoria sull'heap. L'heap ha dimensioni vastissime, e
normalmente è limitato solo dalla memoria disponibile. Allocare la memoria
sull'heap ha un costo (piccolo ma presente), perchè la malloc deve andarsi a
cercare un blocco di memoria. La malloc può fallire, ritornando un puntatore
NULL. La memoria allocata dalla malloc NON viene liberata automaticamente!
La devi liberare a mano. Fino a quando non la liberi continua ad essere
occupata da TE! Ci puoi fare quello che vuoi! Ricordati di liberare la
memoria allocata con la malloc! Ricordati di liberare la memoria allocata
con la malloc! Ricordati di liberare la memoria allocata con la malloc!
Ricordati di liberare la memoria allocata con la malloc! Ricordati di
liberare la memoria allocata con la malloc!
free(NULL) è sempre valido! Ricordatelo!
E' buona norma AZZERARE i puntatori dopo aver fatto free! (a = NULL)
--- bye!

 Questo non si può fare...
Scusa ma AKAIK la dimensione di un array, al di la dei problemi di scope,
deve essere definita a compile time. Quindi le dichiarazioni di b e a[] che
hai riportato dovrebbero essere legali.
Illegale sarebbe cercare di passare la dimensione dell'array a run time, ad
esempio attraverso una scanf.
O sbaglio?
Deep

 conosciuta dal compilatore.
tuttavia il compilatore conosce la dimensione di b, ed arrivati ad
eseguire l'istruzione "int a[b]" lui sa dove andare a prendere il valore
'b' (sia esso dichiarato come variabile automatica nella stessa funzione
sia esso passato per argomento..); difatti, se vado a compilare questo
void foo()
{
	int b = 5;
	int a[b];
}
non ottengo errori da parte del mio compilatore (gcc 3.2.3). A questo
punto mi chiedo (e vi chiedo), se programmando faccio una cosa del genere,
devo considerare la mia soluzione non portabile ? Più dettagliatamente,
perché il compilatore si dovrebbe lamentare ?
Matiz

 perché il compilatore si dovrebbe lamentare ?
Perchč lo standard stabilisce cosě. Mi pare un motivo suffciente :-)
-- 
Gerolamo
www.overweb.it

ringrazio tutti
ed in particolare quelli che non mi hanno creato confusione...
(chi?)


> E' invece legale in C99.
Non che sia molto difficile, con il C99, visto che ci sono i VLA :-)
Questo perņ non č legale senza il C99, vero?
void foo(const int b)
{
  int a[b];
}
--- bye

 }
Uhm... secondo me è legale anche in C89 e C++, ma, notando le
implicazioni di una cosa così, mi viene da dire che un controllino lo
dovrei fare...
-- 
Gerolamo (appena ho tempo...)
www.overweb.it

 dovrei fare...
Chiaramente dà errore :-) Ho provato con il VisualC++. Se non avesse dato
errore, allora sarebbe stata una violazione del fatto che il compilatore
deve sapere la lunghezza dell'array. Qui la lunghezza dell'array veniva
scoperta solo a runtime.
--- bye

 ha scritto nel messaggio
news:6e03c.17696$O31.8...@news4.tin.it...

Vero, ma non mi hai convinto.
Lo standard specifica che la dimensione deve essere conosciuta a compile
time o solo che la forma deve essere:
  tipo nome[espressione_costante]
?
Nel secondo caso sarebbe legale.
Ed era quello che volevo controllare...
-- 
Gerolamo
www.overweb.it

 time o solo che la forma deve essere:
La prima. (Parliamo ovviamente di C89 e C++.)
Max