PDA

View Full Version : [C] Funzione free


D4rkAng3l
29-04-2005, 17:35
Ho scritto questo semplice programmino che alloca dinamicamente un array con calloc, poi lo riempie e infine dovrebbe liberare la memoria precedentemente allocata con free ma quest'ultimo punto mi crea qualche problema....come mai non mi libera la memoria?

#include <stdlib.h>
#include <stdio.h>

/* Non riceve alcun parametro ed emette un puntatore a float */
int * get_mem(void);

int main(void){

int i;
int *puntatore; // Puntatore al primo valore float dell'array allocato

/* Alloca la memoria dinamicamente e metti il valore del puntatore uscente
dalla funzione get_mem nellaa variabile puntatore */

puntatore = get_mem();


printf("\nValore contenuto in puntatore: %p\n\n\n\n", puntatore);

for(i=0; i<100; i++){
*(puntatore + i) = i; // Inizializza l'array con il valore di i
}

/* Visualizza l'array allocato dinamicamente */

for(i=0; i<100; i++){
printf("Indirizzo: %p Valore: %d\n", &puntatore[i],puntatore[i]);
}
printf("\n\n\n\n\nValore contenuto in puntatore: %p\n\n\n\n", puntatore);

/* Libera la memoria precendetemente allocata */

for(i=0; i<100; i++)
free(puntatore[i]);

printf("%d", puntatore[2]);

system("PAUSE");
return 0;
}

/* La funzione get_mem non riceve alcun parametro in ingresso e restituisce un
puntatore al primo valore di tipo float dell'array di 100 elementi allocato
dinamicamente */

int *get_mem(void){

int *p; // Puntatore al primo elemento di tipo float dell'array

/* Alloca memoria per un array di 100 elementi di tipo float */
p = calloc(100, sizeof(int));

if(!p){ // Se calloc restituisce un puntatore NULL
printf("Errore di allocazione della memoria\n");
exit(1);
}
return p;
}

Ziosilvio
29-04-2005, 17:46
Non vorrei sbagliare, ma quando usi malloc e calloc devi sempre convertire a puntatore al tipo che vuoi.
Prova a usare questa:
int *get_mem(void)
{
int *p;

p = (int*)calloc(100*sizeof(int));
if (p==NULL)
exit(1);

return p;
}
o questa:
int *get_mem(void)
{
void *p;

p = calloc(100*sizeof(int));
if (p==NULL)
exit(1);

return (int*)p;
}

AnonimoVeneziano
29-04-2005, 17:47
prima di tutto la sintassi č sbagliata.

A free() devi passare un puntatore , non un dato.

facendo "free(puntatore[i]);" passi il valore contenuto in "puntatore[i]" alla funzione free() che cercherā di liberare la memoria all' indirizzo di memoria indicato da puntatore[i] (e quindi 1, 2, 3 , 4 , 5 ,6 ... strano che non ti sia andato in segmentation fault) .

per liberare tutto l'array č sufficiente dare "free(puntatore);" e dovrebbe andare.

In ogni caso c'č la possibilitā che i valori rimangano in memoria e che quindi visualizzi ugualmente il valore. Infatti free() non cancella la memoria, semplicemente la rende disponibile per un altro programma che ne abbia necessitā. Comunque accedere a una locazione di memoria non allocata come fai nella riga :

printf("%d", puntatore[2]);

a seconda del sistema operativo potrebbe portare a un segmentation fault.

Ciao

Ciao

D4rkAng3l
29-04-2005, 17:51
prima di tutto la sintassi č sbagliata.

A free() devi passare un puntatore , non un dato.

facendo "free(puntatore[i]);" passi il valore contenuto in "puntatore[i]" alla funzione free() che cercherā di liberare la memoria all' indirizzo di memoria indicato da puntatore[i] (e quindi 1, 2, 3 , 4 , 5 ,6 ... strano che non ti sia andato in segmentation fault) .

per liberare tutto l'array č sufficiente dare "free(puntatore);" e dovrebbe andare.

In ogni caso c'č la possibilitā che i valori rimangano in memoria e che quindi visualizzi ugualmente il valore. Infatti free() non cancella la memoria, semplicemente la rende disponibile per un altro programma che ne abbia necessitā. Comunque accedere a una locazione di memoria non allocata come fai nella riga :

printf("%d", puntatore[2]);

a seconda del sistema operativo potrebbe portare a un segmentation fault.

Ciao

Ciao


mmm grazie...ora provo...la cosa strana č che sul McGrowHill faceva come avevo scritto io...poi vi posto il suo esempio :eek:

Ziosilvio
29-04-2005, 17:51
Ancora un altro paio di cose:
free(puntatore[i]);
puntatore[i] č un int, non un puntatore a int; e non dovresti potergli applicare free.
Il compilatore ti dovrebbe dare quantomeno un warning.
Devi chiamare direttamente:
free(puntatore);
che libera tutta la memoria che hai allocato a partire da lė.
Solo che, a quel punto, la chiamata a printf non sarebbe lecita in quanto fai riferimento a una zona della memoria che non č pių allocata.

EDIT: stavo scrivendo questo post quando AnonimoVeneziano ha inserito la sua replica...

Ziosilvio
29-04-2005, 17:53
mmm grazie...ora provo...la cosa strana č che sul McGrowHill faceva come avevo scritto io...poi vi posto il suo esempio :eek:
Di quale McGraw-Hill parli? Sarā mica il Bullschildt (http://catb.org/~esr/jargon/html/B/bullschildt.html)?

D4rkAng3l
29-04-2005, 18:58
perchč non č buono?io mi ci trovo bene...sicuramente meglio del daitel & daitle...che ha che non vā?

Ziosilvio
29-04-2005, 19:33
che ha che non vā?
Se hai seguito il link che ho inserito nel mio post precedente, dovresti avere giā un indizio.
L'articolo all'origine di tutto č questo (http://www.plethora.net/~seebs/c/c_tcr.html).
Anche su ACCU.org (http://www.accu.org/bookreviews/public/reviews/0au/s.htm) (Association of C and C++ Users) non lo trattano certo bene.

AnonimoVeneziano
29-04-2005, 20:50
perchč non č buono?io mi ci trovo bene...sicuramente meglio del daitel & daitle...che ha che non vā?


Il deitel & deitel per me č un buon libro :stordita: :fagiano:

D4rkAng3l
01-05-2005, 12:07
Il deitel & deitel per me č un buon libro :stordita: :fagiano:
si per caritā perō ripete sempre le stesse cose, per spiegarti una cosa ti fā i discorsi lunghissimi....

anx721
01-05-2005, 12:42
ma almeno ti dice le cose corrette e non ti scrive cose sbagliate :mbe: