---
title: "Allocator em Zig — O que é e Como Usar"
url: "https://ziglang.com.br/glossario/allocator-em-zig-o-que-%C3%A9-e-como-usar/"
markdown_url: "https://ziglang.com.br/glossario/allocator-em-zig-o-que-%C3%A9-e-como-usar.MD"
description: "Entenda o conceito de Allocator em Zig: a abstração de gerenciamento de memória que dá controle total ao programador. Exemplos práticos em pt-BR."
date: "2026-02-21"
author: "Zig Brasil"
---

# Allocator em Zig — O que é e Como Usar

Entenda o conceito de Allocator em Zig: a abstração de gerenciamento de memória que dá controle total ao programador. Exemplos práticos em pt-BR.


# Allocator em Zig — O que é e Como Usar

## Definição

Um **Allocator** (alocador) em Zig é uma abstração que encapsula a lógica de alocação e desalocação de memória. Diferentemente de linguagens como C, onde você usa diretamente `malloc` e `free`, ou de linguagens com garbage collector como Java e Go, Zig oferece uma **interface padronizada** (`std.mem.Allocator`) que permite trocar a estratégia de alocação sem alterar o código que a consome.

Em termos simples, o allocator é um "objeto" que sabe como pedir memória ao sistema e devolvê-la. Toda função da biblioteca padrão que precisa alocar memória recebe um allocator como parâmetro — essa é uma decisão de design fundamental da linguagem.

## Por que Allocators Importam

1. **Controle explícito**: Você sempre sabe onde e quando memória é alocada.
2. **Testabilidade**: Em testes, você pode usar um allocator que detecta memory leaks automaticamente.
3. **Performance**: Diferentes situações pedem diferentes estratégias (arena, pool, page).
4. **Sem alocação oculta**: Nenhuma função aloca memória "por baixo dos panos" sem que você saiba.

## Exemplo Prático

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

pub fn main() !void {
    // Criando um General Purpose Allocator
    var gpa = std.heap.GeneralPurposeAllocator(.{}){};
    defer {
        const status = gpa.deinit();
        if (status == .leak) @panic("Vazamento de memória detectado!");
    }

    const allocator = gpa.allocator();

    // Alocando uma lista dinâmica
    var lista = std.ArrayList(u32).init(allocator);
    defer lista.deinit();

    try lista.append(10);
    try lista.append(20);
    try lista.append(30);

    for (lista.items) |valor| {
        std.debug.print("Valor: {}\n", .{valor});
    }
}
```

Neste exemplo, o `GeneralPurposeAllocator` é criado, e sua interface `allocator()` é passada para o `ArrayList`. O `defer` garante que a memória será liberada ao final do escopo.

## Como Funciona a Interface

A interface `std.mem.Allocator` define três operações fundamentais:

```zig
// Simplificação da interface
pub const Allocator = struct {
    allocFn: fn (self: *anyopaque, len: usize, ...) ?[*]u8,
    resizeFn: fn (self: *anyopaque, buf: []u8, new_len: usize, ...) ?usize,
    freeFn: fn (self: *anyopaque, buf: []u8, ...) void,
};
```

Qualquer tipo que implemente essas funções pode ser usado como allocator. Isso permite criar alocadores personalizados para situações específicas.

## Exemplo com ArenaAllocator

O `ArenaAllocator` é ideal para operações onde muitos objetos são criados juntos e liberados de uma só vez — como processar uma requisição HTTP ou fazer parsing de um arquivo:

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

fn processarRequisicao(alocador_base: std.mem.Allocator, dados: []const u8) !void {
    // Arena vive enquanto a requisição durar
    var arena = std.heap.ArenaAllocator.init(alocador_base);
    defer arena.deinit(); // libera tudo de uma vez no final

    const alloc = arena.allocator();

    // Múltiplas alocações sem se preocupar com cada free
    const copia = try alloc.dupe(u8, dados);
    var lista = std.ArrayList([]const u8).init(alloc);
    try lista.append(copia);

    // Todas as alocações acima são liberadas automaticamente
    // quando arena.deinit() é chamado pelo defer
    _ = lista;
}
```

## Passando Allocator para Funções

A convenção em Zig é que funções que precisam alocar memória recebem o allocator como primeiro ou segundo parâmetro:

```zig
// Convenção: allocator como parâmetro explícito
fn criarMensagem(allocator: std.mem.Allocator, nome: []const u8) ![]u8 {
    return std.fmt.allocPrint(allocator, "Olá, {s}!", .{nome});
}

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

    const msg = try criarMensagem(alloc, "Mundo");
    defer alloc.free(msg);
    std.debug.print("{s}\n", .{msg});
}
```

Essa convenção torna explícito que a função aloca memória, e o chamador controla qual estratégia usar — testando com `std.testing.allocator` ou em produção com um arena.

## Comparação com Outras Linguagens

| Abordagem | Linguagem | Controle | Previsibilidade |
|-----------|-----------|----------|----------------|
| Allocators explícitos | Zig | Total | Alta |
| `malloc`/`free` | C | Total | Baixa (sem abstração) |
| Garbage Collector | Go, Java | Nenhum | Baixa (GC pauses) |
| Ownership/borrow | Rust | Total | Alta |
| Smart pointers | C++ | Parcial | Média |

A principal vantagem do modelo Zig é que o allocator é uma abstração testável e substituível — o mesmo código pode rodar com um allocator de produção ou com `std.testing.allocator` (que detecta leaks automaticamente em testes).

## Armadilhas Comuns

- **Esquecer o `defer deinit()`**: Sempre que alocar, garanta a desalocação com `defer`. Sem isso, você terá vazamentos de memória.
- **Usar o allocator errado**: Em contextos de alta performance com muitas alocações curtas, prefira um `ArenaAllocator` em vez do `GeneralPurposeAllocator`.
- **Misturar allocators**: Não aloque com um allocator e desaloque com outro. O comportamento é indefinido.
- **Ignorar falhas de alocação**: `alloc()` retorna um error union. Sempre trate o possível erro com `try` ou `catch`.

## Tipos de Allocator Disponíveis

| Allocator | Uso recomendado |
|-----------|----------------|
| `GeneralPurposeAllocator` | Uso geral, com detecção de bugs |
| `ArenaAllocator` | Muitas alocações, uma única liberação |
| `FixedBufferAllocator` | Sem alocação do sistema, usa buffer fixo |
| `page_allocator` | Alocações grandes, alinhadas a páginas |

## Termos Relacionados

- [Arena Allocator](/glossario/arena-allocator/) — Alocador que libera tudo de uma vez
- [Page Allocator](/glossario/page-allocator/) — Alocador baseado em páginas do SO
- [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/)
- [Introdução ao Zig](/tutoriais/introducao-ao-zig/)
- [Zig para Programadores C](/tutoriais/zig-para-programadores-c/)
