Molto spesso, malloc
e free
utilizzano servizi di allocazione della memoria virtuale di livello inferiore e allocano più pagine (o anche megabyte) contemporaneamente, utilizzando chiamate di sistema come mmap e munmap (e forse sbrk). Spesso malloc
preferisce riutilizzare precedentemente free
d spazio di memoria quando pertinente. La maggior parte malloc
le implementazioni utilizzano varie e diverse strategie per allocazioni "grandi" e "piccole", ecc...
Si noti che lo spazio degli indirizzi virtuali può essere limitato, ad es. con setrlimit(2). Utilizzare su Linux pmap(1) e proc(5) per saperne di più sullo spazio degli indirizzi virtuali di alcuni processi (ad es. /proc/self/maps
per il tuo o /proc/1234/maps
- anche il pmap 1234
comando - per processo di pid 1234).
Potresti guardare il tuo codice sorgente GNU libc, esaminare il codice sorgente di altre librerie standard C (come musl-libc), leggere malloc
implementazioni, scegline altre o implementane di tue, oppure usa strace per scoprirlo sperimentalmente.
Leggi la pagina man di syscalls (ovvero syscalls(2)) e il file <asm/unistd.h>
per un elenco di chiamate di sistema.
un malloc
molto veloce
Credo fermamente che lo standard C sia molto vago su malloc
e free
. Sono abbastanza sicuro che le seguenti funzioni rispettino la lettera (ma non lo spirito) dello standard:
/* politically incorrect, but very probably standard conforming */
void *malloc (size_t sz) { if (sz>0) errno = ENOMEM; return NULL; }
void free(void*ptr) { }
Ovviamente codificherai calloc
e realloc
di conseguenza.
La GNU libc ti dà degli hook per il tuo malloc
funzioni (e probabilmente potresti anche usare Boehm's Garbage Collector in modo trasparente attraverso di esse). Questi hook potrebbero diventare deprecati e non sono standard.
Se usi GNU libc, dai un'occhiata anche a mallinfo(3) e malloc_stat(3) e alle relative funzioni.
malloc
e free
sono funzioni di libreria C standard che devono essere implementate da ciascuna implementazione C.
Lo standard C definisce solo il modo in cui queste funzioni si comportano e il comportamento previsto da esse. Come devono essere implementati a sinistra per ogni implementazione.
In breve, sono i dettagli dell'implementazione dell'implementazione che utilizzi.
(Una "implementazione" consiste nel compilatore, nel linker, nella libreria di runtime e probabilmente in poche altre cose.)