Non esiste una cosa come "chiamare malloc
su una variabile".
malloc
trova una memoria "libera", la contrassegna come "utilizzata" e restituisce l'indirizzo dell'inizio della memoria appena trovata. free
contrassegna alcuni "usati" come "liberi".
Quando si esegue
*foo = malloc(10);
avviene quanto segue:
malloc
trova 10 byte di memoria libera.
malloc
contrassegna quei 10 byte come usati.
malloc
restituisce l'indirizzo dell'inizio dei 10 byte appena trovato.
- Il programma visualizza il valore di
foo
, che è un indirizzo perché foo
è un puntatore.
- Il programma memorizza l'indirizzo
malloc
restituito, all'indirizzo memorizzato in foo
.
malloc
non potrebbe importare di meno ciò che fa il programma con l'indirizzo restituito. Non gli importa se il tuo programma lo memorizza in una semplice variabile, in un array, in un altro spazio di malloc
o addirittura lo scrive in un file. Non importa nemmeno se il tuo programma dimentica l'indirizzo, ma dovresti aver cura, perché il tuo programma non sarà mai in grado di chiamare free
se non conosce l'indirizzo della memoria che sta tentando di liberare.
Data questa conoscenza, si dovrebbe essere in grado di vedere cosa fa questo codice:
char *bar;
bar = malloc(10);
bar = malloc(10);
free(bar);
Prenditi il tuo tempo per capirlo, allora continuate a leggere qui di seguito:
- Una variabile denominata
bar
viene dichiarata ed. Il suo tipo è char*
.
- Il programma chiama
malloc
.
malloc
trova 10 byte liberi e li contrassegna come utilizzati.
malloc
restituisce l'indirizzo dell'inizio dei 10 byte.
- Il programma memorizza l'indirizzo in
bar
. (bar
ora contiene l'indirizzo dei primi 10 byte)
- Il programma chiama
malloc
.
malloc
trova 10 ulteriori byte liberi e li contrassegna come usati.
malloc
restituisce l'indirizzo dell'inizio dei 10 byte.
- Il programma memorizza l'indirizzo in
bar
. (bar
ora contiene l'indirizzo dei secondi 10 byte)
- Il programma chiama
free
e passa l'indirizzo dell'inizio dei secondi 10 byte.
free
contrassegna i secondi 10 byte come liberi.
Questa è una perdita di memoria. I primi 10 byte non verranno mai liberati. Posso dire che non verranno mai liberati, perché il programma non sa in che indirizzo si trovano.
Ma che dire di questo programma?
char *bar;
char *baz;
bar = malloc(10);
baz = bar;
baz = malloc(10);
Qui ho chiamato malloc
"on" una variabile che era già in mano l'indirizzo di qualcosa malloc
ed. Quindi questa è una perdita di memoria? Non da solo. Il programma potrebbe ancora free
il primo blocco di memoria, il cui indirizzo è ancora memorizzato in baz
.
Ma, questo è sicuramente una perdita di memoria:
void func()
{
char *bar;
char *baz;
bar = malloc(10);
baz = bar;
baz = malloc(10);
}
non ho ancora cambiato il codice, ma solo mettendo in una funzione, è ora una perdita di memoria! Whaaaaaaaaa?
Ricordare cosa è effettivamente una perdita di memoria. Una perdita di memoria è quando un programma alloca la memoria ma non la libera mai. Non si può sapere se un programma libera tutta la sua memoria semplicemente guardando le chiamate malloc
.
Per quanto riguarda la seconda parte, "dovrei farlo?"
No, non si dovrebbe.
Esso funziona solo se il vecchio valore all'indirizzo passato alla funzione è un puntatore malloc
ed, e se il chiamante è dimenticato di free
esso.
tuo suggerimento si romperà una di queste funzioni:
void func1()
{
char c;
char *ptr = &c;
memtest(&ptr); // Tries to free something that wasn't malloced!
// ... do something with ptr ...
}
void func2()
{
char *ptr;
memtest(&ptr); // Passes a garbage address to free!
// ... do something with ptr ...
}
void func3()
{
char *ptr1 = malloc(5)
char *ptr2 = ptr1;
memtest(&ptr1);
// ... do something with ptr1 and ptr2 ...
free(ptr1); // Frees memory that was already freed!
}
in conclusione: la domanda nel titolo do non ha senso E rilevare perdite di memoria non è così semplice. E quello che stai cercando di fare è una cattiva idea.
La domanda sarebbe meglio se aggiungeste uno snippet di codice. – haccks
Non esiste una cosa come "chiamare malloc su una variabile". – immibis