C Academy · Lezione

Come funziona malloc

L'heap e le free list.

Lezione 1 di 413 passaggi

Come funziona malloc è una lezione C Academy gratuita su CoddyKit. Questa è la lezione 1 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento C Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso C Academy include 4 lezioni in totale.

Che cosa fa davvero malloc

Quando si chiama malloc(n), la libreria C fornisce un puntatore ad almeno n byte utilizzabili. Tuttavia, l'heap è semplicemente una regione della memoria del processo che l'allocatore gestisce per conto del programma.

Il compito dell'allocatore è tenere traccia di quali byte sono in uso, quali sono liberi e come riutilizzare in modo efficiente la memoria liberata.

L'heap proviene dal sistema operativo

L'allocatore non crea memoria dal nulla. Chiede al sistema operativo grandi blocchi tramite chiamate di sistema come brk/sbrk o mmap.

Quindi suddivide questi blocchi in blocchi più piccoli per le chiamate a malloc. Chiedere memoria al sistema operativo è costoso, quindi gli allocatori la richiedono in grandi quantità e la riciclano.

/* Conceptual: grow the heap by 4096 bytes */
void *base = sbrk(4096);
if (base == (void *)-1) {
    /* out of memory */
}

sbrk e il program break

sbrk(n) sposta il "program break" in avanti di n byte e restituisce il valore precedente del break. La regione appena resa disponibile diventa spazio utilizzabile nell'heap.

È un meccanismo lineare e semplice, ma non può restituire facilmente la memoria nel mezzo. Gli allocatori moderni preferiscono mmap per le richieste grandi.

void *prev_break = sbrk(0);   /* current break */
sbrk(1024);                   /* grow by 1 KB */
/* prev_break now points to fresh memory */

Metadati dei blocchi

Per ogni allocazione l'allocatore memorizza un piccolo header accanto ai dati: la dimensione e l'indicazione che il blocco sia libero. Questo header permette a free di funzionare usando soltanto il puntatore ai dati restituito dal programma.

Il puntatore ricevuto da malloc punta dopo l'header, perciò i metadati rimangono nascosti.

typedef struct block {
    size_t size;
    int free;
    struct block *next;
} block_t;

Il puntatore subito dopo l'header

Un trucco comune consiste nell'aritmetica dei puntatori: il puntatore dell'utente è header + 1. Dato un puntatore dell'utente, l'header si trova un block_t prima di esso.

È così che free(p) recupera la dimensione del blocco allocato senza che sia necessario passarla esplicitamente.

block_t *hdr = (block_t *)user_ptr - 1;
printf("block size = %zu\n", hdr->size);

Demo di un layout di header minimo

Disponiamo un header su un buffer statico e lo rileggiamo. Questo mostra come un allocatore reale divida una regione in header e payload.

Non vengono effettuate chiamate al sistema operativo, quindi il programma può essere eseguito ovunque.

#include <stdio.h>
#include <stddef.h>

typedef struct { size_t size; int free; } block_t;
static char buffer[256];

int main(void) {
    block_t *h = (block_t *)buffer;
    h->size = 64;
    h->free = 0;
    void *payload = (char *)buffer + sizeof(block_t);
    printf("header bytes = %zu\n", sizeof(block_t));
    printf("payload offset = %ld\n", (long)((char *)payload - buffer));
    printf("size field = %zu\n", h->size);
    return 0;
}

L'idea della free list

Molti allocatori collegano i blocchi liberi in una lista concatenata. Quando si chiama malloc, l'allocatore percorre questa lista alla ricerca di un blocco abbastanza grande.

Quando si chiama free, il blocco viene contrassegnato come libero e reinserito nella lista per essere riutilizzato in seguito, evitando un'altra richiesta al sistema operativo.

block_t *find_free(block_t *head, size_t size) {
    block_t *b = head;
    while (b && !(b->free && b->size >= size))
        b = b->next;
    return b;
}

Che cosa deve fare free

free(p) trova l'header di p, lo contrassegna come libero e, idealmente, lo unisce ai blocchi liberi adiacenti (coalescing) per contrastare la frammentazione.

Chiamare free due volte sullo stesso puntatore o liberare un puntatore che non appartiene all'heap provoca un comportamento indefinito, perché i metadati si corrompono.

void my_free(void *p) {
    if (!p) return;
    block_t *hdr = (block_t *)p - 1;
    hdr->free = 1;
    /* real allocators coalesce neighbors here */
}

Frammentazione

Nel tempo, liberare e allocare blocchi di dimensioni diverse lascia degli spazi vuoti. La frammentazione esterna si verifica quando esiste memoria libera, ma è distribuita in parti troppo piccole per soddisfare una richiesta.

La frammentazione interna è lo spazio inutilizzato all'interno di un blocco più grande del necessario, spesso dovuto all'allineamento o all'arrotondamento.

Requisiti di allineamento

malloc deve restituire memoria allineata per qualsiasi tipo. Nella maggior parte dei sistemi a 64 bit ciò significa un allineamento a 16 byte, sufficiente per max_align_t.

I puntatori non allineati possono causare arresti anomali su alcune CPU o rallentare gli accessi su altre, quindi gli allocatori arrotondano sempre i payload al successivo limite di allineamento.

#include <stdalign.h>
/* alignof(max_align_t) is the strictest required alignment */
size_t a = alignof(max_align_t);

Mettere insieme i componenti

Un allocatore minimale necessita quindi di: una fonte di memoria (un buffer statico, sbrk o mmap), header per ogni blocco, una strategia per trovare lo spazio libero e la gestione dell'allineamento.

Nelle lezioni successive costruiremo questi componenti: prima un bump allocator, poi le free list e infine l'allineamento e la suddivisione dei blocchi.

/* The four pillars of a custom allocator */
/* 1. memory source   2. block headers */
/* 3. free-block search   4. alignment */

Verifica rapida

Verificate la vostra comprensione dei componenti interni di un allocatore.

Riepilogo

malloc gestisce un heap ottenuto dal sistema operativo tramite sbrk o mmap e lo suddivide in blocchi con header nascosti che tengono traccia della dimensione e dello stato di liberazione.

Le free list permettono il riutilizzo, l'allineamento rende la memoria adatta a ogni tipo e la frammentazione rappresenta la difficoltà principale. Queste idee guidano l'allocatore che costruiremo in seguito.

Gratis per iniziare

Impara C con un tutor IA — gratis

Scrivi ed esegui vero codice nel tuo browser, ricevi aiuto istantaneo da un tutor IA disponibile 24/7, e riprendi da dove hai lasciato sul web o nell'app.

Corsi
39
Lezioni
144

Domande Frequenti

La lezione «Come funziona malloc» è gratuita?

Sì — il testo completo di «Come funziona malloc» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso C Academy, passa a CoddyKit PRO. Il corso C Academy include 4 lezioni in totale.

Cosa imparerò in «Come funziona malloc»?

L'heap e le free list. Eserciti C Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare C Academy?

Non è richiesta alcuna esperienza precedente. C Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 1 di 4.

Quanto tempo richiede la lezione «Come funziona malloc»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione C Academy?

Sì. Ogni lezione C Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. Come funziona malloc
  2. Un semplice allocatore bump
  3. Free list e riutilizzo
  4. Allineamento e suddivisione
← Torna a C Academy