---
title: "Stack vs Heap em Zig — O que é e Como Usar"
url: "https://ziglang.com.br/glossario/stack-vs-heap-em-zig-o-que-%C3%A9-e-como-usar/"
markdown_url: "https://ziglang.com.br/glossario/stack-vs-heap-em-zig-o-que-%C3%A9-e-como-usar.MD"
description: "Entenda a diferença entre Stack e Heap em Zig: onde os dados vivem, performance, tempo de vida e quando usar cada um. Guia completo em pt-BR."
date: "2026-02-21"
author: "Zig Brasil"
---

# Stack vs Heap em Zig — O que é e Como Usar

Entenda a diferença entre Stack e Heap em Zig: onde os dados vivem, performance, tempo de vida e quando usar cada um. Guia completo em pt-BR.


# Stack vs Heap em Zig — O que é e Como Usar

## Definição

**Stack** (pilha) e **Heap** (monte) são as duas regiões principais de memória onde dados podem ser armazenados durante a execução de um programa Zig.

- **Stack**: Memória rápida, automática, com tamanho fixo, alocada e liberada em ordem LIFO (último a entrar, primeiro a sair). Variáveis locais vivem na stack.
- **Heap**: Memória dinâmica, gerenciada manualmente via [allocators](/glossario/allocator/), com tamanho flexível. Dados que precisam sobreviver além do escopo da função vivem no heap.

Em Zig, diferente de linguagens com garbage collector, **você controla explicitamente** quando dados vão para o heap.

## Por que Entender Stack vs Heap Importa

1. **Performance**: Stack é ordens de magnitude mais rápida que heap (alocação = mover ponteiro vs syscall).
2. **Tempo de vida**: Dados na stack morrem ao sair do escopo; dados no heap vivem até serem liberados.
3. **Tamanho**: Stack é limitada (tipicamente 8MB); heap é limitada pela RAM disponível.
4. **Previsibilidade**: Stack não fragmenta; heap pode fragmentar com muitas alocações/liberações.

## Exemplo Prático

### Dados na Stack

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

pub fn main() void {
    // Todas estas variáveis vivem na stack
    var x: u32 = 42;
    var buffer: [256]u8 = undefined;
    const ponto = struct { x: f64, y: f64 }{ .x = 1.0, .y = 2.0 };

    x += 1;
    buffer[0] = 'A';
    std.debug.print("x={}, ponto=({d},{d})\n", .{ x, ponto.x, ponto.y });
    // Ao sair de main, tudo é liberado automaticamente
}
```

### Dados no Heap

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

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

    // Alocação no heap — tamanho dinâmico
    const tamanho: usize = obterTamanho(); // valor só conhecido em runtime
    const buffer = try allocator.alloc(u8, tamanho);
    defer allocator.free(buffer);

    // Lista que cresce dinamicamente
    var lista = std.ArrayList(u32).init(allocator);
    defer lista.deinit();

    try lista.append(1);
    try lista.append(2);
    try lista.append(3);

    std.debug.print("Itens: {}\n", .{lista.items.len});
}

fn obterTamanho() usize {
    return 1024;
}
```

### Retornando Dados: Stack vs Heap

```zig
// FUNCIONA: retorna cópia do valor (struct pequena)
fn criarPonto(x: f64, y: f64) struct { x: f64, y: f64 } {
    return .{ .x = x, .y = y };
}

// PERIGOSO: retornar ponteiro para variável local!
fn perigoso() *u32 {
    var local: u32 = 42;
    return &local; // ERRO: dangling pointer!
}

// CORRETO: alocar no heap quando precisa do ponteiro
fn seguro(allocator: std.mem.Allocator) !*u32 {
    const ptr = try allocator.create(u32);
    ptr.* = 42;
    return ptr; // OK: dados vivem no heap
}
```

## Comparação Detalhada

| Característica | Stack | Heap |
|---------------|-------|------|
| Velocidade | Muito rápida | Mais lenta |
| Tamanho | Limitado (~8MB) | Limitado pela RAM |
| Gerenciamento | Automático | Manual (allocator) |
| Fragmentação | Nenhuma | Possível |
| Tamanho dos dados | Fixo em compilação | Dinâmico em runtime |
| Thread safety | Cada thread tem sua stack | Compartilhado entre threads |
| Localidade de cache | Excelente | Variável |

## Quando Usar Cada Um

**Use Stack quando:**
- O tamanho é conhecido em tempo de compilação
- Os dados são pequenos (< alguns KB)
- Os dados só são necessários no escopo atual

**Use Heap quando:**
- O tamanho é determinado em runtime
- Os dados são grandes (ex: buffers de MB)
- Os dados precisam sobreviver além do escopo
- Você precisa de estruturas que crescem (ArrayList, HashMap)

## O Terceiro Caminho: Stack com FixedBufferAllocator

O `FixedBufferAllocator` combina o melhor dos dois mundos: usa um buffer da stack como backing store, mas expõe a interface de `Allocator`, permitindo estruturas dinâmicas (ArrayList, HashMap) sem nenhuma syscall ou fragmentação de heap. Quando o buffer da stack é destruído ao sair do escopo, toda a memória é liberada automaticamente — sem nenhum `defer free` individual necessário.

## Perguntas Frequentes

**Posso aumentar o tamanho da stack?** Sim, mas é dependente de plataforma. Em Zig, ao criar threads com `std.Thread.spawn`, você pode especificar o tamanho da stack. Para a thread principal, o limite é definido pelo sistema operacional.

**Structs grandes devem ir para o heap?** Não necessariamente. Uma struct de 4KB na stack é segura. O problema são arrays de MB. Use bom senso: se cabe razoavelmente na stack (< centenas de KB) e tem tempo de vida claro, deixe na stack.

**Passar por valor ou por ponteiro?** Para tipos pequenos (< 16 bytes), passar por valor é geralmente mais rápido. Para tipos grandes, passe por ponteiro ou referência para evitar cópias.

## Armadilhas Comuns

- **Stack overflow**: Arrays muito grandes na stack (ex: `var buffer: [10_000_000]u8`) causam stack overflow. Use heap para dados grandes.
- **Dangling pointers**: Retornar ponteiros para variáveis locais da stack é comportamento indefinido.
- **Memory leaks**: Esquecer de liberar memória do heap com `defer allocator.free()`.
- **Assumir tamanho da stack**: O tamanho da stack varia entre plataformas. Não assuma 8MB.

## Termos Relacionados

- [Allocator](/glossario/allocator/) — Interface de alocação de memória
- [Arena Allocator](/glossario/arena-allocator/) — Alocador que libera tudo junto
- [Memory Leak](/glossario/memory-leak/) — Vazamentos de memória
- [Dangling Pointer](/glossario/dangling-pointer/) — Ponteiros pendentes

## Tutoriais Relacionados

- [Gerenciamento de Memória em Zig](/tutoriais/gerenciamento-de-memoria-zig/)
- [Zig Segurança de Memória](/tutoriais/zig-seguranca-memoria/)
- [Introdução ao Zig](/tutoriais/introducao-ao-zig/)
