Newsgroup: it.comp.lang.c
Titolo: Implementazione della malloc e della free

Ciao a tutti!
La funzione malloc alloca uno spazio di memoria nello stack o nello heap? 
Potete dirmi, ad alto livello, come funzionano queste due istruzioni? Es. La 
malloc verifica che nello stack/heap ci sia spazio libero a sufficienza, lo 
segna come utilizzato e quindi restituisce il puntatore alla prima posizione 
della zona di memoria riservata, oppure c'è dell'altro? Stessa cosa per la 
funzione free.
Grazie in anticipo.
Riccardo Rossi. 

 Riccardo Rossi. 
Di niente
P.S.: Spero di non aver detto fesserie :)
-- 
Quando noi ignoranti eravamo di piů, tutto era piů bello (A. Celentano).
  ___   _   ___ _  _______   _______ ___
|   \ /_\ | _ \ |/ / _ ) \ / /_   _| __|
| |) / _ \|   / ' <| _ \\ V /  | | | _|
|___/_/ \_\_|_\_|\_\___/ |_|   |_| |___|

 dell'altro? Stessa cosa per la funzione free.
se c'è memoria a disposizione, viene restituito un puntatore alla locazione
iniziale, altrimenti restituisce NULL.
free() non fa altro che cancellare la locazione di memoria passata come
parametro...prima di chiamare la free() è sempre opportuno verificare che
questa non sia nulla, e di norma dopo la free() il programmatore deve
settare il puntatore a NULL per evitare che una chiamata free() accidentale
possa cancellare il suo contenuto ( dopo la free, il puntatore può puntare
a qualsiasi locazione, anche di sistema o riservata!).


 questa non sia nulla
No. E' un cosa che si vede in molti sorgenti, ma è una verfica perfettamente
inutile (almeno con i compilatori moderni). Lo standard prevede che a
'free' possa essere passato un puntatore nullo, nel qual caso "no action
occurs" (C89, 4.10.3.2).
Max

 Potete dirmi, ad alto livello, come funzionano queste due istruzioni?
Ad alto livello, basta leggere un qualsiasi manuale delle due funzioni. La
malloc() ritorna NULL oppure l'indirizzo di un'area di memoria grande almeno
tanti byte quanto indicato dall'argomento. La free(), se il suo argomento è
NULL non fa niente; se l'argomento è uno degli indirizzi ritornati da
malloc() rilascia la memoria (cosa significhi "rilasciare" non è però
specificato; se è un altro valore potrebbe fare di tutto.
La più semplice implementazione possibile delle due funzioni è ovviamente
questa:
   void * malloc (size_t size)
   {
      return NULL;
   }
   void free (void * p)
   {
   }
Implementazione perfettamente standard... e perfettamente inutile.
Ecco un'altra implementazione giocattolo, solo leggermente meno inutile:
   void * malloc (size_t size)
   {
      static char Heap [1000];
      static size_t Used = 0;
      if (size > 0 && Used + size <= sizeof(Heap))
      {
         Used += size;
         return Heap + Used - size;
      }
      return NULL;
   }
   void free (void * p)
   {
   }
Ovviamente, le implementazioni vere sono un bel po' più complesse.
In genere, le funzioni si basano su qualche funzione del sistema operativo
per allocare e rilasciare la memoria. Queste funzioni sono spesso molto meno
flessibili di quanto devono esserlo malloc() e free(): per esempio,
potrebbero avere delle limitazioni sulla dimensione minima del pezzo di
memoria da allocare (tipicamente, il minimo sarà 1, 4, 8 o 16 kilobyte),
oppure potrebbero richiedere di rilasciare la memoria nell'ordine inverso a
quello in cui è stata allocata, ecc.
Queste limitazioni vengono spesso mascherate usando una lista della memoria
libera:
la free() non fa altro che aggiungere il pezzo di memoria da rilasciare
nella lista; la malloc() scorre questa lista cercando un pezzetto di memoria
di dimensioni adeguate: la funzione di allocazione del sistema operativo
viene chiamanta solo quando la lista non contiene un pezzo adeguato.
Un esempio di implementazione basata sulla lista di memoria libera lo trovi
nella sezione 8.7 del Kernninghan & Ritchie.
--
Cingar
--------------------------------
Inviato via 
http://arianna.libero.it/usenet/

 Ovviamente, le implementazioni vere sono un bel po' più complesse.
si, anche se su Windows, ad esempio, la seguente implementazione e'
funzionale:
<CODE>
void* TomMalloc(size_t size)
{
    return VirtualAlloc(
        NULL, size,
        MEM_RESERVE|MEM_COMMIT,
        PAGE_READWRITE);
}
void TomFree(void* ptr)
{
    VirtualFree(ptr,0,MEM_DECOMMIT|MEM_RELEASE);
}
</CODE>
(ovviamente includendo windows.h).
Tommy