Como funciona malloc
O heap e as listas de memória livre.
Como funciona malloc é uma aula grátis de C Academy no CoddyKit. Esta é a aula 1 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de C Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de C Academy inclui 4 aulas no total.
O que malloc realmente faz
Quando você chama malloc(n), a biblioteca C fornece um ponteiro para pelo menos n bytes utilizáveis. Porém, o heap é apenas uma região da memória do processo que o alocador gerencia em seu nome.
A tarefa do alocador é manter registros: acompanhar quais bytes estão em uso, quais estão livres e como reutilizar a memória liberada com eficiência.
O heap vem do OS
O alocador não cria memória do nada. Ele solicita grandes blocos ao sistema operacional por meio de chamadas de sistema como brk/sbrk ou mmap.
Depois, divide esses blocos em unidades menores para suas chamadas a malloc. Solicitar memória ao OS é caro, portanto os alocadores pedem memória em grandes quantidades e a reciclam.
/* Conceptual: grow the heap by 4096 bytes */
void *base = sbrk(4096);
if (base == (void *)-1) {
/* out of memory */
}sbrk e o limite do programa
sbrk(n) move o "limite do programa" para cima em n bytes e retorna o limite anterior. A região recém-exposta passa a ser espaço disponível no heap.
Esse mecanismo é linear e simples, mas não consegue devolver facilmente memória no meio da região. Os alocadores modernos preferem mmap para solicitações grandes.
void *prev_break = sbrk(0); /* current break */
sbrk(1024); /* grow by 1 KB */
/* prev_break now points to fresh memory */Metadados do bloco
Para cada alocação, o alocador armazena um pequeno cabeçalho ao lado dos dados: o tamanho e a indicação de que está livre ou não. Esse cabeçalho permite que free funcione apenas com o ponteiro para os dados que você devolve.
O ponteiro recebido de malloc aponta depois do cabeçalho, portanto os metadados ficam ocultos para você.
typedef struct block {
size_t size;
int free;
struct block *next;
} block_t;Ponteiro logo depois do cabeçalho
Um recurso comum é a aritmética de ponteiros: o ponteiro do usuário é header + 1. Dado um ponteiro do usuário, o cabeçalho está uma block_t antes dele.
É assim que free(p) recupera o tamanho do bloco alocado sem que você precise informá-lo.
block_t *hdr = (block_t *)user_ptr - 1;
printf("block size = %zu\n", hdr->size);Demonstração de um layout de cabeçalho pequeno
Vamos colocar um cabeçalho sobre um buffer estático e lê-lo de volta. Isso mostra como um alocador real divide uma região em cabeçalho e carga útil.
Nenhuma chamada ao OS é feita, portanto o programa é executado em qualquer lugar.
#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;
}A ideia da lista de blocos livres
Muitos alocadores encadeiam os blocos livres em uma lista ligada. Quando você chama malloc, o alocador percorre essa lista procurando um bloco grande o suficiente.
Quando você chama free, o bloco é marcado como livre e devolvido à lista para reutilização posterior, evitando outra solicitação ao OS.
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;
}O que free precisa fazer
free(p) encontra o cabeçalho de p, marca-o como livre e, idealmente, combina-o com blocos livres adjacentes (coalescência) para combater a fragmentação.
Chamar free duas vezes para o mesmo ponteiro ou liberar um ponteiro que não pertence ao heap gera comportamento indefinido, pois os metadados ficam corrompidos.
void my_free(void *p) {
if (!p) return;
block_t *hdr = (block_t *)p - 1;
hdr->free = 1;
/* real allocators coalesce neighbors here */
}Fragmentação
Com o tempo, liberar e alocar tamanhos diferentes deixa lacunas. A fragmentação externa significa que existe memória livre, mas ela está espalhada em partes pequenas demais para atender a uma solicitação.
A fragmentação interna é o espaço desperdiçado dentro de um bloco maior do que o necessário, geralmente devido ao alinhamento ou ao arredondamento.
Requisitos de alinhamento
malloc deve retornar memória alinhada para qualquer tipo. Na maioria dos sistemas de 64 bits, isso significa alinhamento de 16 bytes, atendendo a max_align_t.
Ponteiros desalinhados podem causar falhas em algumas CPUs ou tornar o acesso mais lento em outras, portanto os alocadores sempre arredondam as cargas úteis para cima até um limite de alinhamento.
#include <stdalign.h>
/* alignof(max_align_t) is the strictest required alignment */
size_t a = alignof(max_align_t);Juntando tudo
Portanto, um alocador mínimo precisa de: uma fonte de memória (buffer estático, sbrk ou mmap), cabeçalhos por bloco, uma estratégia para encontrar espaço livre e tratamento de alinhamento.
Nas próximas lições, construiremos essas partes: primeiro um alocador bump, depois listas de blocos livres e, por fim, alinhamento e divisão de blocos.
/* The four pillars of a custom allocator */
/* 1. memory source 2. block headers */
/* 3. free-block search 4. alignment */Verificação rápida
Teste sua compreensão dos componentes internos de um alocador.
Recapitulação
malloc gerencia um heap obtido do OS por meio de sbrk ou mmap, dividindo-o em blocos com cabeçalhos ocultos que registram o tamanho e o estado de cada bloco.
As listas de blocos livres permitem a reutilização, o alinhamento mantém qualquer tipo adequado e a fragmentação é o desafio central. Essas ideias orientam o alocador que construiremos a seguir.
Perguntas Frequentes
A aula “Como funciona malloc” é grátis?
Sim — o texto completo de “Como funciona malloc” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de C Academy, atualize para CoddyKit PRO. O curso de C Academy inclui 4 aulas no total.
O que vou aprender em “Como funciona malloc”?
O heap e as listas de memória livre. Você pratica C Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.
Preciso ter experiência prévia para começar C Academy?
Nenhuma experiência prévia é necessária. C Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 1 de 4.
Quanto tempo leva a aula “Como funciona malloc”?
A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.
Posso escrever e executar código nesta aula de C Academy?
Sim. Cada aula de C Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.
Todas as aulas deste curso
- Como funciona malloc
- Um alocador bump simples
- Listas livres e reutilização
- Alinhamento e divisão