Newsgroup: it.comp.lang.c
Titolo: ripulire la ram dopo una malloc

esempio:
char *scrivi()
{
     char szMem, buffer[100];
     strcpy(buffer,"dati ricavati da input...");
     szMem=(char*)malloc(strlen(buffer));
     strcpy(szMem,buffer);
     return(szMem);
}
char richaimo[101];
strcpy(richiamo,scrivi());
Come posso liberare la memoria ram occupata da questa malloc???


free(< nome puntatore>);

 strcpy(richiamo,scrivi());
e poi faccio la free, ma cosě con una malloc da 100 byte non ho guadagnato
niente, suggerimenti????


Ogni segmento di memoria allocato va comunque liberato tramite free(). Non
ci puoi scappare, anche se si tratta solo di 1 byte. Non č una questione di
guadagno, ma di pulizia.

 }
questo non lo fare mai!!!
non devi MAI ritornare l'indirizzo di una variabile locale, perche' quando
la funzione termina, quell'area di memoria non e' piu' valida.
Il tuo problema e' semplicissimo:
char * fun ( void )
{
  char * p;
  ...
  p=malloc( ... );
  ...
  return p;
}
int main ( void )
{
  char * p;
  ...
  p=fun();
  ...
  free(p);
  ...
}
ciao
donCiccio

}
E' errato.
Mai restituire l'indirizzo di una variabile automatica.
--
Walkie...@Libero.It (ICQ# 8143647)


Fermati. Riflettiamoci un minuto.
a) scrivi() come ti hanno gia' detto ritorna il puntatore ad una zona
di memoria "automatica". In cui cioe' l'allocazione di memoria viene
gestita dal compilatore. Queste aree in generale non sono garantite
all'uscita della funzione.
Si puo' in casi particolari farlo, ma bisogna sapere quello che si sta
facendo. E puo' essere pericoloso. In generale meglio evitarlo come
le sette pesti.
b) Inoltre fare un free di un area di quel tipo e' il modo migliore di
bombare il programma..... Il free va utilizzato SOLO per aree su
cui si e' fatta una malloc e SOLO UNA VOLTA.
In generale inizializza sempre i puntatori a NULL, poi fai pure malloc
e quanto devi fare. Quando quella zona di memoria non ti serve piu'
fanne il free e rimetti il puntatore a NULL (altrimenti come fai a sapere
se e' allocata la memoria oppure no?).
Inoltre (in generale) se hai allocato una zona di memoria non spostare
il puntatore provocheresti dei memory leak (perdite di memoria)...
ad esempio:
char *p=NULL, stringa[20]="bello";
p=(char *) malloc(40);
p=strnga;                        //e cosi' si perdono i 40 byte allocati
nella riga precedente
free(p);                            // e cosi' si effettua il free di un
area "protetta" con crash del programma
Questo e' un errore tipico. Prestaci attenzione!!!!
La risposta corretta la trovi nel post di don ciccio ... quindi e' inutile
che la ripeta io...
                                  Andrea Zaghi (visto che ci sono altri
Andrea :-))

p=(char *) malloc(40);
Il cast (char*) non serve.
--
Walkie...@Libero.It (ICQ# 8143647)

 le sette pesti.
E quali sarebbero i casi in cui è possibile farlo? A me risulta che
all'uscita di una funzione tutti i suoi oggetti locali "muoiano" e non
si debba *mai* far riferimento ad essi.
EMG



immagino che si riferisca alle variabili static. Anche se non è del
tutto corretto, visto che in quel caso non è possibile parlare di
memoria "automatica".
Anto
--
Antonio Cuni, 19 anni, studente
Brainbench Certification: 
Master C++: 4.6, higher than 98% of all previous test takers.
C Language: 3.32, higher than 79% of all previous test takers.
http://www.brainbench.com/transcript.jsp?pid=1301688

 Non serve inizializzare il puntatore.
No, non serve ma e' buona norma farlo !
Alex

No, non serve ma e' buona norma farlo !
Ripeto : non serve farlo.
--
Walkie...@Libero.It (ICQ# 8143647)

si debba *mai* far riferimento ad essi.
In effetti epro' uno potrebbe passare a un puntatore globale
l'ěndirizzo di un oggetto locale e farvi riferimento
dall'esterno..naturalemtne questa sarebbe una pratica assurda..poihce'
nessuno garantisce che l'area allocata per l'oggetto locale non sia
stata sovrascritta nel frattempo...
Augusto Pucci ( 
http://www.prospektiva.it/webmaster/
 )
Webmaster di Prospektiva On-line
http://www.prospektiva.it
Webmaster di SIPO Toscana
http://sipotoscana.supereva.it

stata sovrascritta nel frattempo...
Il fatto e' che SICURAMENTE l'ex-area locale alla funzione non e' piu'
valida all'uscita dalla funzione e quindi non ha alcun senso assegnare
quella zona di memoria a un puntatore globale.  
E' un errore gravissimo che non deve essere fatto.
--
Walkie...@Libero.It (ICQ# 8143647)

 stata sovrascritta nel frattempo...
Piů che assurda sarebbe errata in quanto l'oggetto locale viene
rilasciato alla fine della funzione e poco importa se la memoria non č
ancora stata riutilizzata.
EMG

ancora stata riutilizzata.
Credo che la situazione sia anche peggiore... se ricordo
bene secondo lo standard dopo che un'area di memoria e'
stata rilasciata diventa undefined behaviour anche
semplicemente fare riferimento a quell'indirizzo.
Andrea
--
Andrea Griffini, Programmer
http://www.netservers.com/~agriff

 ha scritto nel messaggio
news:3B0CD452...@flashnet.it...

Di buona norma mai......
Ma la memoria definita come
char array[100];
in una funzione viene definita automaticamente come static.
Lo standard non prevede il comportamento della gestione
della memoria al di fuori di dove essa sia definita...
In realta' la stragrande maggioranza dei compilatori la lascia
li' intatta e quindi se uno conosce il comportamento specifico della
"sua" macchina e non gliene frega niente della portabilita'.....
In effetti essendo uno static si e' " quasi sicuri" che il puntatore
ha valore anche al di fuori della funzione e se si effettua subito
la  copia e' "altamente improbabile" anche in caso di funzione
chiamata in continuazione fra vari thread che si sia gia' corrotta....
(sempre per programmi a thread concorrenti che "si danno la mano"
e che non occupino troppa CPU).
Ammetto che esistono metodi piu' puliti.....:-). Non lo consiglio
a nessuno. Non e' il modo giusto di fare le cose.
Nel thread ho visto che giustamente di diceva che non e'
necessario inizialiazzare i puntatori a NULL. Io lo stavo
solo consigliando. E' una pratica che spesso mi ha impedito
di fare cazzate... non e' pero' necessario.
Ho visto anche che qualcuno e' intervenuto sul casting.
Anche questo non necessario. Secondo taluni addirittura dannoso.
Io lo trovo "utile" in quanto rende "per me" piu' leggibile
il codice (per lo stesso motivo odio il typedef).
Considerate pero' che *tutti* i compilatori moderni c (se attivate
le funzioni di warning) vi generano un bel (e fastidioso) warning
per ogni cast implicito, spesso distraendo l'attenzione dal
warning *utile* ad esempio quello che vi dice che fare
if(variabile=0) probabilmente e' uno sbaglio di battitura....
Per questo uso il casting, anche se ribadisco NON SERVE A NULLA.
(Altrimenti qualcuno fara' un post solo per ridirlo).
                                       Andrea Zaghi

 (Altrimenti qualcuno fara' un post solo per ridirlo).
ti consiglio di capire cos'e' il warning segnalato e rimuoverlo in altro
modo, vedi esempio precedente.
ciao
donCiccio

 in una funzione viene definita automaticamente come static.
Ti stai confondendo. Viene definita auto non static.
EMG


ciao
                     Andrea Zaghi

 rientri negli "stili di programmazione": ognuno faccia un po' come gli
pare.
ok
ciao
donCiccio

di fare cazzate... non e' pero' necessario.
In realtà per evitare di fare cazzate il massimo, IMO, è inizializzare il
ptr direttamente col valore che deve assumere, ad es, se ho bisogno di
allocare 45 caratteri di memoria con malloc:
void trallallero(void)
{
    char *p = malloc(sizeof(char) * 45);
    .
    .
    .
    free(p);
    .
}
(sì, ok, sizeof(char) non serve a nulla).
Una tecnica del genere deve essere una buona idea, in quanto ad es. in C++
ci sono i reference che *devono* essere inizializzati alla dichiarazione,
per ottenere un risultato tipo quello dell'esempio ma ancora più sicuro (in
C posso assegnare al ptr qualcos'altro, invece i reference dopo
l'inizializzazione sono costanti).
Lanugo

ancora stata riutilizzata.
Certamente..sarebbe errata come che so sforare i limiti di un array
sperando in un miracolo... oppure usare variabili non inizializzate..




Certo che sarebbe un errore gravissimo..stavo solo chiarendo quelloa
cui probabilmente si stavano riferendo nel post... lungi da me il
ritenere questa una pratica corretta !!!
