Newsgroup: it.comp.programmare
Titolo: Gestione dinamica della memoria in C

Ciao, ho appena cominciato a programmare in c (su DOS), e mi sono imbattuto
nella gestione dinamica della memoria; siccome la spiegazione del libro che
sto utilizzando (trickyC) è un po' ostica su questo argomento, volevo vedere
se avevo capito giusto.
La gestione dinamica si utilizza quando devo allocare ad una variabile dello
spazio in memoria, ma non so quanto, perchè è dipendente da ciò che inserirà
l'utente in un eventuale richiesta di input. Ad esempio, chiedo all'utente
il suo nome, ma nella dichiarazione della variabile char non posso sapere di
quante lettere sarà composto. Ecco che mi servo dell'allocazione dinamica
della memoria (col comando malloc( )), che mi fornisce l'indirizzo della
prima cella di memoria mi è stata messa a disposizione. Il nome verrà
salvato carattere dopo carattere partendo da quell'indirizzo. Giusto...?
Come vedete ciò che ho capito non è molto... ma spero che almeno sia
giusto!!!
Grazie a chiunque mi aiuti!!!
Andrea

salvato carattere dopo carattere partendo da quell'indirizzo. Giusto...?
in parte.... malloc ti restituirà l'indirizzo della prima cella di
memoria libera..... ma che rispecchi le condizioni che tu hai
chiesto.....
infatti malloc chiede come parametro quanti byte allocare in memoria,
quindi se l'input andrà oltre la lunghezza max é tuo compito evitare
ciò, pena un eventuale errore.
cod

 ciò, pena un eventuale errore.
Ma come faccio a sapere quanto spazio mi servirà se, riprendendo
l'esempio del mio primo messaggio, non so di quanti caratteri è composto
il nome dell'utente?  Nel programmino che sto facendo, ho fornito al malloc
il parametro "char"... perchè l'unica cosa che so è che mi serviranno un tot
di spazi che dovranno contenere dei caratteri (quindi di 1 byte ciascuno),
ma
non so quanti!
Ad ogni modo, come faccio ad evitare che l'utente inserisca più di n
caratteri?
Perchè se potessi limitare il numero di caratteri che l'utente inserisce,
allora
non farei prima a dichiarare un bell'array di tipo char, composto da tanti
elementi quanti
ne voglio, tipo:
char nome_utente[10];
e limitare l'input dell'utente a 10 lettere x il suo nome? A che mi serve
allora la gestione dinamica della memoria, se devo comunque sapere
quanto spazio mi serve prima dell'input dell'utente?

Beh, la situazione del nome utente non è un buon esempio di allocazione
dinamica. In casi di questo genere si allocano variabili con una dimensione
predefinita:
char szUsername[64];
Un caso in cui l'allocazione dinamica è più appropriata è ad esempio la
memoria richiesta per il testo di un word processor. L'utente dev'essere
infatti libero di inserire un testo di lunghezza potenzialmente infinita. In
questo caso l'allocazione può essere anche molto complessa, perché devi
rispettare due regole:
1) non sprecare memoria
2) non rallentare l'esecuzione del programma.
Potresti ad esempio allocare un nuovo blocco di memoria grande un char in
più per ogni carattere inserito dall'utente e ricopiarci sopra il vecchio
blocco che così andresti a cancellare... ottima occupazione di memoria ma
PESSIMA in quanto a prestazioni... conviene quindi bufferizzare le
allocazioni, ad esempio 256 caratteri per volta, ed allocarne di nuova
quando si esaurisce lo spazio allocato. Da sconsigliare anche la copiatura
di un blocco su di un altro, conviene mantenere una tabella (o meglio, una
lista linkata) come descrittore di tutti i blocchi allocati...
straordinariamente complesso, no?
Lorenzo


Direi straordinariamente interessante! Non vedo l'ora di imparare il
c ad un livello tale da dovermi porre questo tipo di problemi!!!

 quanto spazio mi serve prima dell'input dell'utente?
Non stai prendendo in considerazione l'esistenza di realloc,
che ti permette di CAMBIARE la quantita` di memoria allocata
(tipicamente facendola crescere).  Puoi leggere i caratteri
immessi uno alla volta, accumulandoli in un vettore dapprima
malloc'ato, e ricorrere a realloc quando il numero di caratteri
sta diventando eccessivo.  Dovrai tenere traccia di quanto
spazio hai allocato sinora.
Queste questioni di lana caprina a bassissimo livello sono
naturalmente inappropriate per chi si sta occupando di fare
funzionare un'applicazione!  Meglio, come minimo, farsi una
*libreria* di funzioni che gia` incapsulino questi problemi
fondazionali.  Meglio ancora passare a linguaggi che sappiano
occuparsi loro della memoria e ti permettano di occuparti
invece delle reali problematiche applicative.  Purtroppo
C++ e` astrusamente complicato -- peccato perche` queste
cose, nella sua libreria standard, le fa bene (ad esempio
la funzione std::getline, chiamata con un parametro che e`
una reference a una std::string, gestisce interamente tutte
le problematiche della lettura di una riga di qualsiasi
numero di carattere).  Python e` il mio linguaggio preferito,
semplice, pulito, e potente, e di questi problemi "si fa
un solo boccone":-).  Altri linguaggi purtroppo soffrono
di problemi di portabilita` (ad esempio esistono solo per
Windows, non per piattaforme tipo Unix o Mac o Palmtop o...).
Comunque non e` che le cose in C "non si possano fare" --
si fanno, eccome, solo che magari ti vuole il doppio del
tempo (di programmazione) che non a farle con linguaggi
che ti semplificano un poco di piu` la vita:-).
Alex (MVP di Brainbench per il C++)

 un solo boccone":-).
Python, eh? Mi hai incuriosito... mi sono scaricato il 2.1, ma
purtroppo il sito in italiano (con il tutorial) non funziona!
Appena riesco ad accedere alla guida, voglio provarlo.
Grazie del consiglio,
Andrea.

 ma se succede? Il programma si impalla, o sbaglio?
Se non impedisci all'utente di inserire più caratteri di quelli consentiti e
scrivessi tutto nell'array, finiresti per sporcare la memoria che segue:
subito adiacenti all'ultimo byte dell'array potrebbero esserci altre
variabili oppure codice eseguibile. È per questo che il C è un linguaggio
"delicato" perché permette di accedere alla memoria tramite i puntatori -
ricordiamo che gli array sono dei puntatori sotto mentite spoglie... infatti
c[2] equivale a *(c+2)
Lorenzo

 Grazie del consiglio,
Prego!  Purtroppo temo che ancor oggi occorra l'inglese per
la maggior parte delle informazioni in rete...
