---
title: "General Purpose Allocator em Zig — O que é e Como Usar"
url: "https://ziglang.com.br/glossario/general-purpose-allocator-em-zig-o-que-%C3%A9-e-como-usar/"
markdown_url: "https://ziglang.com.br/glossario/general-purpose-allocator-em-zig-o-que-%C3%A9-e-como-usar.MD"
description: "Entenda o General Purpose Allocator (GPA) em Zig: alocador de uso geral com detecção de bugs de memória integrada. Guia completo em pt-BR."
date: "2026-02-21"
author: "Zig Brasil"
---

# General Purpose Allocator em Zig — O que é e Como Usar

Entenda o General Purpose Allocator (GPA) em Zig: alocador de uso geral com detecção de bugs de memória integrada. Guia completo em pt-BR.


# General Purpose Allocator em Zig — O que é e Como Usar

## Definição

O **General Purpose Allocator** (GPA, `std.heap.GeneralPurposeAllocator`) é o alocador de uso geral da biblioteca padrão do Zig. Ele combina performance razoável com **detecção integrada de bugs de memória**: vazamentos (memory leaks), double-free, use-after-free e overflows de buffer. É o alocador recomendado para a maioria das aplicações e especialmente para desenvolvimento e testes.

## Por que o GPA Importa

1. **Detecção de bugs**: Em modo Debug, detecta automaticamente os erros de memória mais comuns.
2. **Uso geral**: Funciona bem para a maioria dos padrões de alocação.
3. **Configurável**: Diversas opções para ajustar comportamento e segurança.
4. **Production-ready**: Pode ser usado em produção com configurações de release.

## Exemplo Prático

### Uso Básico com Detecção de Leaks

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

pub fn main() !void {
    var gpa = std.heap.GeneralPurposeAllocator(.{}){};
    defer {
        const status = gpa.deinit();
        if (status == .leak) {
            std.debug.print("ALERTA: Vazamento de memória detectado!\n", .{});
        }
    }

    const allocator = gpa.allocator();

    // Alocação normal
    const dados = try allocator.alloc(u8, 100);
    defer allocator.free(dados);

    // Se esquecêssemos o defer acima, gpa.deinit() detectaria o leak
    std.debug.print("Alocado {} bytes\n", .{dados.len});
}
```

### Configuração Personalizada

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

var gpa = std.heap.GeneralPurposeAllocator(.{
    // Registra stack traces de alocação para debug
    .stack_trace_frames = 8,
    // Não libera memória de volta ao SO (mais rápido para debug)
    .retain_metadata = true,
    // Desabilita safety checks para release
    .safety = true,
}){};
```

### Usando em Testes

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

fn criarLista(allocator: std.mem.Allocator) !std.ArrayList(u32) {
    var lista = std.ArrayList(u32).init(allocator);
    try lista.append(1);
    try lista.append(2);
    try lista.append(3);
    return lista;
}

test "sem memory leak" {
    // testing.allocator já é um GPA com detecção de leaks!
    var lista = try criarLista(testing.allocator);
    defer lista.deinit();

    try testing.expectEqual(@as(usize, 3), lista.items.len);
    // Se esquecer o defer, o teste FALHA automaticamente
}
```

### Detectando Double Free

```zig
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);
    // allocator.free(dados); // PANIC: double free detectado!
}
```

### GPA como Alocador Principal da Aplicação

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

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

    const allocator = gpa.allocator();

    var app = try App.init(allocator);
    defer app.deinit();

    try app.run();
}
```

## O que o GPA Detecta

| Bug | Detecção | Modo |
|-----|----------|------|
| Memory leak | No `deinit()` | Debug + ReleaseSafe |
| Double free | No `free()` | Debug + ReleaseSafe |
| Use-after-free | No acesso | Debug |
| Buffer overflow | Na escrita | Debug |

## Armadilhas Comuns

- **Esquecer de chamar `deinit()`**: Sem `deinit()`, a detecção de leaks não ocorre. Sempre use `defer _ = gpa.deinit()`.
- **Performance em hot paths**: O GPA é mais lento que alocadores especializados. Para hot paths, considere `ArenaAllocator`.
- **Ignorar o status de deinit**: O retorno de `deinit()` informa se houve leak. Verifique-o.
- **Usar em freestanding**: O GPA depende do sistema operacional. Em embarcados, use `FixedBufferAllocator`.
- **Confundir com `testing.allocator`**: `testing.allocator` já é um GPA configurado para testes. Não crie outro dentro de testes.

## Quando Usar o GPA

O GPA é o alocador correto para a maioria das aplicações, mas existem situações onde outros alocadores se encaixam melhor:

| Situação | Alocador recomendado |
|----------|---------------------|
| Desenvolvimento e testes | GPA (detecção de bugs) |
| Aplicação geral em produção | GPA |
| Processamento de requisição HTTP | ArenaAllocator |
| Hot path com muitas alocações pequenas | ArenaAllocator |
| Ambiente embarcado sem SO | FixedBufferAllocator |
| Teste unitário | `testing.allocator` (já é um GPA) |

Uma prática comum em código Zig de produção é usar o GPA como alocador raiz e delegar para alocadores especializados (como `ArenaAllocator`) em contextos específicos:

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

    // Para cada requisição, usa uma arena filha
    var arena = std.heap.ArenaAllocator.init(allocator);
    defer arena.deinit();
    const req_alloc = arena.allocator();

    try processarRequisicao(req_alloc);
}
```

## Boas Práticas

- **Use `defer _ = gpa.deinit()`**: O underscore descarta o valor de retorno deliberadamente quando você não quer checar o status de leak.
- **Verifique o status em testes**: Em testes, cheque explicitamente se o deinit retorna `.ok` para garantir que não há vazamentos.
- **Não compartilhe o GPA entre threads sem sincronização**: O GPA não é thread-safe por padrão. Use sincronização externa ou um allocator por thread.

## Termos Relacionados

- [Allocator](/glossario/allocator/) — Interface de alocação de memória
- [Arena Allocator](/glossario/arena-allocator/) — Alocador para liberação em lote
- [Page Allocator](/glossario/page-allocator/) — Alocador baseado em páginas
- [Fixed Buffer Allocator](/glossario/fixed-buffer-allocator/) — Alocador com buffer fixo
- [Memory Leak](/glossario/memory-leak/) — Vazamentos de memória

## Tutoriais Relacionados

- [Gerenciamento de Memória em Zig](/tutoriais/gerenciamento-de-memoria-zig/)
- [Testes em Zig](/tutoriais/testes-zig/)
- [Zig Debugging](/tutoriais/zig-debugging/)
