O que é uma falha de segmentação (segmentation fault)?
Uma falha de segmentação (segmentation fault, ou segfault) é um travamento que acontece quando um programa tenta ler ou escrever em uma memória que não tem permissão para acessar, como o endereço 0 por meio de um ponteiro nulo. O sistema operacional encerra o programa com o sinal SIGSEGV.
Atualizado em 24 de setembro de 2026
Um programa C imprime a primeira linha e depois para com uma mensagem que ninguém escreveu:
#include <stdio.h>
int main(void) {
int *score = NULL;
printf("About to read the score\n");
printf("Score: %d\n", *score);
return 0;
}
About to read the score
bash: line 1: 64030 Segmentation fault: 11 ./seg
Essa saída é do bash no macOS, onde 64030 é o ID do processo e 11 é o número do sinal. No Linux o mesmo travamento costuma aparecer como Segmentation fault (core dumped), ou, com o sistema em português, "Falha de segmentação (imagem do núcleo gravada)". De qualquer forma, o programa nunca imprimiu a nota. score guarda o endereço 0, e *score pede ao processador para ler a memória nesse endereço, o que nenhum programa tem permissão de fazer.
Como uma falha de segmentação acontece
Todo programa executa no seu próprio espaço de endereçamento virtual, uma faixa enorme de endereços que o sistema operacional preenche aos poucos. Ele mapeia o código do programa, as variáveis globais, a pilha (stack) e o heap nessa faixa, em blocos chamados páginas (4 KB na maioria dos sistemas Linux x86, 16 KB nos Macs com Apple silicon). A maioria dos endereços fica sem mapeamento, e o endereço 0 está sempre entre eles, para que bugs de ponteiro nulo sejam detectados.
- O programa executa uma instrução que lê ou escreve em um endereço. Aqui é a leitura de
*score, endereço 0. - A unidade de gerenciamento de memória do processador procura o endereço na tabela de páginas. A página não está mapeada, ou o programa está tentando escrever em uma página somente leitura.
- O processador interrompe a instrução e passa o controle ao kernel com uma falha de página (page fault).
- O kernel verifica se o acesso poderia ser legítimo, por exemplo uma pilha que precisa crescer. Não é, então o kernel envia ao processo o sinal 11,
SIGSEGV. - A ação padrão para
SIGSEGVé encerrar o processo e, quando o sistema permite, salvar um core dump. O shell então imprime a mensagem e define o status de saída como 139, que é 128 mais o número do sinal.
Então uma falha de segmentação não é informada pelo compilador, e não é uma exceção lançada pela linguagem. É o hardware e o kernel protegendo a memória, o que a torna um erro de tempo de execução do tipo mais abrupto. O Windows trata o mesmo evento como uma violação de acesso, código de exceção 0xC0000005.
Causas comuns de falhas de segmentação
C e C++ deixam um programa calcular qualquer endereço e usá-lo, então as causas se resumem a usar um endereço que não é válido.
- Desreferenciar um ponteiro nulo.
int *p = NULL; *p = 5;Uma função que retornaNULLquando falha, comomallocoufopen, leva a isso quando o resultado não é verificado. - Um índice muito além do fim de um array. O C não verifica limites, então
arr[1000000]é simplesmente um endereço um milhão de elementos adiante. - Usar memória depois do
free. O ponteiro ainda guarda o endereço antigo, mas a memória não pertence mais a você. - Um ponteiro não inicializado.
int *p; *p = 5;escreve por meio de qualquer valor lixo quepestiver guardando. - Estouro de pilha (stack overflow). Uma função recursiva sem caso de parada continua adicionando quadros à pilha até passar do fim dela. O exemplo abaixo travou no macOS com
Segmentation fault: 11e status de saída 139. - Escrever em uma string literal.
char *name = "coddy"; name[0] = 'C';tenta mudar memória somente leitura. No Linux isso é um segfault. No macOS o mesmo programa parou comBus error: 10, um sinal parecido.
#include <stdio.h>
int depth(int n) {
return depth(n + 1) + 1; /* never stops calling itself */
}
int main(void) {
printf("%d\n", depth(0));
return 0;
}
Um erro pequeno muitas vezes nem trava, o que o torna mais perigoso. Este loop lê um elemento além do fim de um array de três elementos:
#include <stdio.h>
int main(void) {
int scores[3] = {72, 88, 95};
int total = 0;
for (int i = 0; i <= 3; i++) { /* <= reads scores[3] */
total += scores[i];
}
printf("Total: %d\n", total);
return 0;
}
Compilado com o Clang em um Mac, ele imprimiu Total: 256. O total correto é 255. scores[3] eram os 4 bytes seguintes da pilha, que pertenciam ao programa, então nenhuma falha ocorreu e o valor lixo foi somado em silêncio. O sistema operacional só interrompe acessos a memória que não pertence ao programa de jeito nenhum.
A correção para os dois erros é o mesmo hábito: saiba quantos elementos existem e verifique um ponteiro antes de segui-lo.
Best: 95
No scores, nothing to read
O que significa "core dumped"
Um core dump é um arquivo que guarda uma cópia da memória do programa no momento em que ele travou. Um depurador pode abri-lo depois e mostrar exatamente onde o programa estava e o que as variáveis guardavam: gdb ./app core. Em muitas distribuições Linux, o systemd-coredump coleta esses arquivos, e coredumpctl list os mostra. Quando os core dumps estão desativados, por exemplo com ulimit -c 0, a mensagem é só Segmentation fault, sem as palavras entre parênteses.
Como encontrar a linha que travou
A linha em que o programa trava muitas vezes não é a linha com o bug. Um ponteiro pode se tornar inválido em uma função e ser usado em outra muito depois. Estas ferramentas mostram as duas.
Um depurador. Compile com informações de depuração e execute o programa dentro do depurador. Quando ele parar, bt (backtrace) imprime a cadeia de chamadas de função com nomes de arquivo e números de linha. No Linux o depurador costuma ser o gdb; no macOS é o lldb, onde bt funciona do mesmo jeito.
gcc -g app.c -o app
gdb ./app
(gdb) run
(gdb) bt
AddressSanitizer. Compile com -fsanitize=address (GCC e Clang suportam) e execute o programa normalmente. Em vez de um segfault seco, ele imprime um relatório que nomeia o tipo de erro, como heap-use-after-free ou stack-buffer-overflow, com a linha que fez o acesso e a linha que alocou a memória. Ele também detecta a leitura silenciosa de um elemento além do fim mostrada acima, que nunca trava sozinha.
Valgrind. No Linux, valgrind ./app executa um programa sem modificações e informa toda leitura ou escrita inválida, como Invalid read of size 4.
Falhas de segmentação em outras linguagens
Python, Java e JavaScript verificam cada índice e cada referência antes de usá-los, então os mesmos erros viram exceções com mensagens claras: IndexError ou AttributeError em Python, ArrayIndexOutOfBoundsException ou NullPointerException em Java, TypeError em JavaScript. Essas podem ser capturadas com tratamento de exceções. Um segfault não pode ser tratado assim: é um sinal, e um bloco catch do C++ não o vê.
Programas Python ainda podem ter segfault quando o código C por baixo deles falha. Esta linha pede ao ctypes para ler o endereço 0:
import ctypes
ctypes.string_at(0)
Executado com python3 -X faulthandler, o Python 3.12 imprimiu Fatal Python error: Segmentation fault, seguido das linhas Python que estavam executando. O mesmo travamento acontece quando uma extensão em C ou uma biblioteca nativa tem um bug de memória. O Rust segue outro caminho: o compilador rejeita, antes de o programa ser gerado, a maior parte do código que poderia acessar memória inválida.
Próximos passos
O guia de C sobre falhas de segmentação percorre cada causa com um programa mínimo e a sua correção. Para evitar os erros desde o início, leia sobre ponteiros, ponteiros nulos e a pilha e o heap, e depois pratique no curso de C. Para ver como os erros são informados em linguagens que verificam a memória por você, veja a página de erro de tempo de execução.
Perguntas frequentes
Como corrigir uma falha de segmentação?
-g e execute o programa dentro do gdb ou do lldb, depois digite bt após o travamento, ou compile com -fsanitize=address para um relatório detalhado. Então corrija o ponteiro ou o índice que essa linha usa: verifique se os ponteiros são NULL, mantenha os índices de array abaixo do tamanho, pare de usar a memória depois do free e garanta que a recursão termine.Uma falha de segmentação é um vazamento de memória?
free, como usar um ponteiro depois de liberá-lo, podem causar segfaults, enquanto esquecer o free causa vazamentos.Por que se chama falha de segmentação?
SIGSEGV, ficaram. O Windows chama o mesmo evento de violação de acesso (access violation).Um programa Python pode ter segmentation fault?
ctypes. Executar python -X faulthandler script.py imprime as linhas Python que estavam executando quando ele travou.O que significa o código de saída 139?
SIGSEGV, uma falha de segmentação. Os shells informam uma morte por sinal como 128 mais o número do sinal, e 128 + 11 = 139. No Docker e no Kubernetes, um contêiner que sai com 139 teve um segfault no processo principal.