---
title: "Segmentation Fault — Como Resolver em Zig"
url: "https://ziglang.com.br/erros/segmentation-fault-como-resolver-em-zig/"
markdown_url: "https://ziglang.com.br/erros/segmentation-fault-como-resolver-em-zig.MD"
description: "Entenda o Segmentation Fault (segfault) em Zig, causado por acesso inválido à memória. Veja como diagnosticar e corrigir esse erro de runtime."
date: "2026-02-21"
author: "Zig Brasil"
---

# Segmentation Fault — Como Resolver em Zig

Entenda o Segmentation Fault (segfault) em Zig, causado por acesso inválido à memória. Veja como diagnosticar e corrigir esse erro de runtime.


# Segmentation Fault — Como Resolver em Zig

## O Que Este Erro Significa

O Segmentation Fault (segfault ou SIGSEGV) ocorre quando o programa tenta acessar uma região de memória que não lhe pertence ou que não está mapeada. O sistema operacional detecta o acesso ilegal e encerra o processo com um sinal SIGSEGV. Em Zig, apesar do sistema de segurança em builds Debug, segfaults ainda podem ocorrer em determinadas situações, especialmente quando se usa ponteiros brutos, código `@cImport`-ado ou builds ReleaseFast.

A mensagem típica é:

```
Segmentation fault at address 0x0
```

Ou o programa simplesmente é encerrado pelo sistema operacional.

## Causas Comuns

### 1. Desreferenciar Ponteiro Null

```zig
pub fn main() void {
    var ptr: ?*u32 = null;
    // Converte optional para ponteiro bruto (bypass de segurança)
    const raw: *u32 = @ptrFromInt(0);
    _ = raw.*; // SEGFAULT: endereço 0x0
    _ = ptr;
}
```

### 2. Uso de Ponteiro Após Free (Dangling Pointer)

```zig
const std = @import("std");

pub fn main() !void {
    var gpa = std.heap.GeneralPurposeAllocator(.{}){};
    defer _ = gpa.deinit();
    const allocator = gpa.allocator();

    const dados = try allocator.alloc(u8, 100);
    allocator.free(dados);

    // SEGFAULT: memória já foi liberada
    dados[0] = 42;
}
```

### 3. Acesso a Memória Não Inicializada

```zig
pub fn main() void {
    var buffer: [100]u8 = undefined;
    // Em ReleaseFast, undefined pode ser qualquer valor
    const ptr: *u32 = @ptrCast(@alignCast(&buffer));
    _ = ptr.*;
    // Pode causar SEGFAULT dependendo do conteúdo de buffer
}
```

### 4. Interação com Código C Inseguro

```zig
const c = @cImport({
    @cInclude("stdlib.h");
    @cInclude("string.h");
});

pub fn main() void {
    const ptr = c.malloc(100);
    c.free(ptr);
    // SEGFAULT: uso após free via API C
    _ = c.memset(ptr, 0, 100);
}
```

### 5. Stack Overflow Que Se Manifesta como Segfault

```zig
fn recursaoInfinita() void {
    recursaoInfinita(); // Estoura a stack
    // Pode aparecer como segfault ao invés de stack overflow
}

pub fn main() void {
    recursaoInfinita();
}
```

## Como Corrigir

### Solucao 1: Sempre Verificar Optionals Antes de Usar

```zig
const std = @import("std");

pub fn main() void {
    var ptr: ?*u32 = null;

    if (ptr) |p| {
        std.debug.print("valor: {}\n", .{p.*});
    } else {
        std.debug.print("Ponteiro é null\n", .{});
    }
}
```

### Solucao 2: Evitar Ponteiros Após Free

```zig
const std = @import("std");

pub fn main() !void {
    var gpa = std.heap.GeneralPurposeAllocator(.{}){};
    defer _ = gpa.deinit();
    const allocator = gpa.allocator();

    const dados = try allocator.alloc(u8, 100);
    defer allocator.free(dados); // defer garante free no momento certo

    // Usa dados enquanto são válidos
    dados[0] = 42;
    dados[99] = 255;
    // free acontece aqui automaticamente via defer
}
```

### Solucao 3: Inicializar Memória Explicitamente

```zig
const std = @import("std");

pub fn main() void {
    // Use valor concreto ao invés de undefined
    var buffer = std.mem.zeroes([100]u8);
    // Ou use @memset
    @memset(&buffer, 0);

    // Agora é seguro usar buffer
    buffer[0] = 42;
}
```

### Solucao 4: Usar Slices ao Invés de Ponteiros Brutos

```zig
const std = @import("std");

fn processar(dados: []u8) void {
    // Slices têm verificação de limites em Debug
    for (dados) |*byte| {
        byte.* = 0;
    }
}

pub fn main() !void {
    var gpa = std.heap.GeneralPurposeAllocator(.{}){};
    defer _ = gpa.deinit();
    const allocator = gpa.allocator();

    const buffer = try allocator.alloc(u8, 100);
    defer allocator.free(buffer);

    processar(buffer);
}
```

### Solucao 5: Compilar em Modo Debug para Diagnóstico

Compile com modo Debug (padrão) para obter mensagens de erro melhores:

```bash
zig build        # Modo Debug por padrão
zig build-exe main.zig  # Também Debug por padrão
```

Em modo Debug, muitos segfaults são transformados em panics com stack trace legível:

```
thread 1 panic: index out of bounds
/home/user/main.zig:12:15: 0x20401a in main
```

### Solucao 6: Wrapping Seguro de Código C

```zig
const c = @cImport({
    @cInclude("stdlib.h");
});

fn alocarSeguro(tamanho: usize) !*anyopaque {
    const ptr = c.malloc(tamanho);
    if (ptr == null) return error.OutOfMemory;
    return ptr.?;
}

fn liberarSeguro(ptr: *anyopaque) void {
    c.free(ptr);
}
```

## Ferramentas de Diagnóstico

### Usando address sanitizer (ASan)

Zig pode compilar com sanitizers para detectar problemas de memória:

```bash
zig build-exe -fsanitize=address main.zig
```

### Usando Valgrind

```bash
zig build-exe main.zig
valgrind ./main
```

### Stack Trace em Debug

Em builds Debug, Zig fornece stack traces detalhados. Sempre desenvolva em modo Debug primeiro e só mude para ReleaseFast/ReleaseSafe quando necessário.

## Diferenças entre Modos de Build

| Modo         | Verificações de Segurança | Segfault Detectado Como |
|-------------|--------------------------|------------------------|
| Debug        | Todas                    | Panic com stack trace  |
| ReleaseSafe  | Todas                    | Panic com stack trace  |
| ReleaseFast  | Nenhuma                  | Segfault bruto         |
| ReleaseSmall | Nenhuma                  | Segfault bruto         |

Segfaults são um problema exclusivo de linguagens com acesso direto a ponteiros. <a href="https://rustlang.com.br/artigos/rust-ownership-borrowing/" target="_blank" rel="noopener" onclick="umami.track('portfolio-site-click', { destination: 'rustlang.com.br' })">Rust elimina a maioria dos segfaults com o borrow checker</a>, enquanto <a href="https://golang.com.br/artigos/go-garbage-collector/" target="_blank" rel="noopener" onclick="umami.track('portfolio-site-click', { destination: 'golang.com.br' })">Go os evita com garbage collection e runtime safety checks</a>.

## Erros Relacionados

- [Use after free](/erros/erro-use-after-free/) — Uso de memória após liberação
- [Stack overflow](/erros/erro-stack-overflow/) — Estouro da pilha de execução
- [Index out of bounds](/erros/erro-index-out-of-bounds/) — Acesso fora dos limites
- [Null unwrap](/erros/erro-null-unwrap/) — Desempacotar optional null

## Links Úteis

- [Documentação oficial do Zig — Safety](https://ziglang.org/documentation/master/#Safety)
- [Receitas de depuração](/receitas/)
- [Tutorial sobre ponteiros em Zig](/tutoriais/)
