---
title: "Arena Allocator em Zig — O que é e Como Usar"
url: "https://ziglang.com.br/glossario/arena-allocator-em-zig-o-que-%C3%A9-e-como-usar/"
markdown_url: "https://ziglang.com.br/glossario/arena-allocator-em-zig-o-que-%C3%A9-e-como-usar.MD"
description: "Entenda Arena Allocator em Zig: o alocador que libera toda memória de uma vez. Ideal para requisições e processamento em lote. Guia em pt-BR."
date: "2026-02-21"
author: "Zig Brasil"
---

# Arena Allocator em Zig — O que é e Como Usar

Entenda Arena Allocator em Zig: o alocador que libera toda memória de uma vez. Ideal para requisições e processamento em lote. Guia em pt-BR.


# Arena Allocator em Zig — O que é e Como Usar

## Definição

O **Arena Allocator** (`std.heap.ArenaAllocator`) em Zig é um alocador que agrupa múltiplas alocações e as libera **todas de uma vez** com uma única operação (`deinit` ou `reset`). Chamadas individuais a `free` são no-ops (não fazem nada). A arena obtém memória de um alocador "pai" (backing allocator) em blocos grandes e distribui fatias desses blocos.

É o alocador mais eficiente quando você tem um padrão de "alocar muita coisa, depois liberar tudo junto".

## Por que Arena Allocator Importa

1. **Performance**: Alocação é quase instantânea (incrementa um ponteiro). Liberação é O(1).
2. **Simplicidade**: Não precisa gerenciar `free` individual — `deinit` libera tudo.
3. **Sem fragmentação**: Alocações são sequenciais dentro dos blocos.
4. **Padrão ideal para requisições**: Aloca durante o processamento, libera ao final da requisição.

## Exemplo Prático

### Uso Básico

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

pub fn main() !void {
    var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
    defer arena.deinit(); // Libera TODA a memória de uma vez

    const allocator = arena.allocator();

    // Todas essas alocações são rápidas
    const nome = try allocator.alloc(u8, 100);
    const dados = try allocator.alloc(u32, 500);
    const config = try allocator.create(Config);

    // Não precisa de free individual!
    // arena.deinit() cuida de tudo
    _ = nome;
    _ = dados;
    _ = config;
}

const Config = struct { porta: u16, debug: bool };
```

### Padrão de Requisição HTTP

```zig
fn handleRequest(request: *Request, response: *Response) !void {
    // Arena para esta requisição
    var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
    defer arena.deinit(); // Tudo limpo ao final da requisição

    const alloc = arena.allocator();

    const body = try parseBody(alloc, request.body);
    const usuario = try buscarUsuario(alloc, body.user_id);
    const html = try renderTemplate(alloc, "perfil.html", usuario);

    try response.send(html);
    // Sem memory leak possível — arena libera tudo
}
```

### Reset para Reutilização

```zig
fn processarLote(items: []const Item) !void {
    var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
    defer arena.deinit();

    for (items) |item| {
        // Reset mantém a memória alocada do SO, mas permite reutilizar
        _ = arena.reset(.retain_capacity);

        const alloc = arena.allocator();
        const resultado = try processarItem(alloc, item);
        try salvarResultado(resultado);
    }
}
```

### Arena como Scratch Allocator

```zig
fn algoritmoComplexo(allocator: std.mem.Allocator) !Resultado {
    // Arena para alocações temporárias internas
    var scratch = std.heap.ArenaAllocator.init(allocator);
    defer scratch.deinit();

    const temp = scratch.allocator();

    // Muitas alocações temporárias durante o cálculo
    var intermediario = try temp.alloc(f64, 10000);
    _ = intermediario;
    var buffer = try temp.alloc(u8, 4096);
    _ = buffer;

    // Resultado final alocado com o allocator "real"
    const resultado = try allocator.create(Resultado);
    resultado.* = calcular();
    return resultado;
}
```

## Quando Usar Arena

| Cenário | Arena é boa? |
|---------|-------------|
| Processamento de requisição | Sim |
| Compilador/parser (por fase) | Sim |
| Game loop (por frame) | Sim |
| Estrutura de longa duração | Não (use GPA) |
| Alocações com lifetimes variados | Não |

## Armadilhas Comuns

- **Reter referências após deinit/reset**: Qualquer ponteiro obtido da arena se torna inválido após `deinit` ou `reset`. Isso cria [dangling pointers](/glossario/dangling-pointer/).
- **Arena que nunca é liberada**: Em loops longos sem `reset`, a arena acumula memória indefinidamente.
- **Free individual não faz nada**: Chamar `free` em uma alocação de arena não libera memória. Isso é por design.
- **Escolher o backing allocator errado**: Use `page_allocator` para programas normais, ou outro allocator para contextos especiais.

## Boas Práticas com Arena

**Combine Arena com GPA como backing allocator**: Em vez de usar `page_allocator` diretamente, use o GPA como backing. Assim você ainda detecta vazamentos do GPA enquanto aproveita a performance da arena:

```zig
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = gpa.deinit();

var arena = std.heap.ArenaAllocator.init(gpa.allocator());
defer arena.deinit();

const alloc = arena.allocator();
```

**Use `reset(.retain_capacity)` em loops de alta performance**: Esta opção descarta as alocações lógicas mas mantém a memória alocada do sistema, evitando novas chamadas ao SO a cada iteração:

```zig
for (entradas) |entrada| {
    defer _ = arena.reset(.retain_capacity);
    const resultado = try processarEntrada(arena.allocator(), entrada);
    try salvar(resultado);
}
```

**Não misture lifetimes dentro da arena**: Todos os dados da arena têm o mesmo lifetime — o da arena. Não retorne ponteiros internos da arena para escopos mais externos a não ser que o lifetime da arena também cubra esse escopo.

## Comparação com Outras Linguagens

Em C, o padrão equivalente seria implementar manualmente um bump allocator: manter um ponteiro de topo e simplesmente avançá-lo a cada alocação, `free` em lote com `memset` ou `munmap`. Em C++, `std::pmr::monotonic_buffer_resource` (C++17) implementa o mesmo conceito. Em Rust, o crate `bumpalo` oferece arena allocation. A vantagem do Zig é que a Arena é parte da biblioteca padrão e integra-se perfeitamente à interface `std.mem.Allocator`, permitindo que qualquer função que aceite um allocator possa usar a arena sem modificações.

## Termos Relacionados

- [Allocator](/glossario/allocator/) — Interface de alocação de memória
- [Page Allocator](/glossario/page-allocator/) — Alocador baseado em páginas
- [General Purpose Allocator](/glossario/general-purpose-allocator/) — Alocador de uso geral
- [Memory Leak](/glossario/memory-leak/) — Vazamentos de memória
- [Stack vs Heap](/glossario/stack-vs-heap/) — Diferença entre pilha e heap

## Tutoriais Relacionados

- [Gerenciamento de Memória em Zig](/tutoriais/gerenciamento-de-memoria-zig/)
- [Zig Design Patterns](/tutoriais/zig-design-patterns/)
- [Servidor HTTP em Zig](/tutoriais/zig-http-server/)
