Causas de segmentation faults em C e como corrigi-los — seu guia completo de erros em tempo de execução.
x / 0).Segmentation fault (core dumped) é o erro que iniciantes mais encontram. Significa "você tocou em memória que não tinha permissão para acessar."int a[5]; a[10] = 99; // só existem a[0]..a[4]; escrever a[10] = crash imediato // Erro comum: limite de laço errado for (int i = 0; i <= 5; i++) // acessa a[5] quando i=5 -> Errado a[i] = i;
int *p = NULL; *p = 10; // escrevendo no endereço para o qual NULL aponta -> Segfault // Correção: verifique NULL antes de usar if (p != NULL) { *p = 10; }
int x; scanf("%d", x); // Errado: usa o "valor" de x como endereço -> crash scanf("%d", &x); // OK: passa o "endereço" de x
int *p; // não inicializado -> contém endereço de lixo *p = 42; // escrevendo em endereço de lixo -> Segfault // Correção: sempre inicialize, ou aloque com malloc antes de usar
int fact(int n) { return n * fact(n - 1); // sem caso base -> recursão infinita -> stack overflow } // Correção: adicione if (n <= 1) return 1;
char name[5]; strcpy(name, "HelloWorld"); // só 5 bytes mas 10+NUL -> overflow // Correção: strncpy(name, "Hello", sizeof(name)-1);
free na memória alocada por malloc deixa memória inalcançável que se acumula ao longo do tempo.int *p = malloc(sizeof(int) * 100); // ... usa p ... // esqueceu free(p); -> vazamento de memória
free(p); *p = 10; // escrevendo em memória liberada -> comportamento indefinido free(p); // double free -> possível crash // Correção: defina p = NULL; após free
int a = 7, b = 2; double avg = a / b; // -> 3.000000 (não 3.5!) double avg = (double)a / b; // -> 3.500000 (OK)
if (x & 1 == 0) // é lido como x & (1==0) — não é o que você quis! if ((x & 1) == 0) // OK: parênteses explícitos
switch (n) { case 1: printf("one\n"); // sem break -> case 2 e 3 também rodam case 2: printf("two\n"); case 3: printf("three\n"); }
if (x > 0); // ← este ; encerra a instrução if { printf("positive\n"); // ← sempre executa! }
R. Erros de compilação são problemas de sintaxe detectados durante a compilação; nenhum executável é produzido. Erros em tempo de execução acontecem enquanto o programa está rodando — o código compila, mas o programa trava. Erros em tempo de execução são mais difíceis de detectar.
R. Segmentation faults vêm de acesso ilegal a memória. Os principais culpados: (1) desreferenciar um ponteiro NULL, (2) acessar memória liberada, (3) acesso a array fora dos limites e (4) stack overflow. Revise o manuseio de ponteiros e memória.
R. (1) Verifique a condição do laço e o critério de saída. (2) Use printf() nas variáveis do laço para ver onde elas divergem do esperado. (3) Um depurador passo a passo também é eficaz. A maioria dos laços infinitos vem de condições ruins ou incremento ausente.
R. Corrupção de memória é complicada porque os sintomas frequentemente aparecem longe da causa real. Ferramentas eficazes incluem (1) valgrind (Linux/Mac), (2) sanitizers como UBSan e ASan e (3) revisão cuidadosa do uso de arrays e ponteiros.
Confira seu entendimento.
Causas comuns incluem desreferenciar ponteiros NULL, acesso a array fora dos limites e uso de memória liberada. O compilador não detecta nenhum deles.
Divisão inteira por 0 é um erro em tempo de execução. Se estiver dividindo por uma variável, verifique primeiro se ela não é zero.
Laços infinitos acontecem quando a condição de saída nunca é atendida. Verifique se há uma atualização de contador ausente ou lógica da condição com falhas.