---
title: "OutOfMemory — Como Resolver em Zig"
url: "https://ziglang.com.br/erros/outofmemory-como-resolver-em-zig/"
markdown_url: "https://ziglang.com.br/erros/outofmemory-como-resolver-em-zig.MD"
description: "Entenda o erro OutOfMemory em Zig, que ocorre quando o alocador não consegue fornecer a memória solicitada. Veja causas, diagnóstico e soluções."
date: "2026-02-21"
author: "Zig Brasil"
---

# OutOfMemory — Como Resolver em Zig

Entenda o erro OutOfMemory em Zig, que ocorre quando o alocador não consegue fornecer a memória solicitada. Veja causas, diagnóstico e soluções.


# OutOfMemory — Como Resolver em Zig

## O Que Este Erro Significa

O erro `OutOfMemory` ocorre quando um alocador de memória em Zig não consegue satisfazer uma requisição de alocação. Diferente de linguagens com garbage collector, em Zig toda alocação de memória é explícita e pode falhar. Quando o sistema operacional não tem memória disponível suficiente, ou quando o alocador atinge um limite interno, a operação de alocação retorna `error.OutOfMemory`.

Este é um dos erros mais fundamentais em Zig, pois qualquer função que aloca memória pode potencialmente retorná-lo. Ele faz parte do error set de praticamente todas as funções da biblioteca padrão que fazem alocações dinâmicas.

## Causas Comuns

### 1. Alocação de Memória Muito Grande

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

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

    // Tentando alocar 1 TB de memória — provavelmente falhará
    const buffer = try allocator.alloc(u8, 1_000_000_000_000);
    // error.OutOfMemory
    defer allocator.free(buffer);
}
```

### 2. Vazamento de Memória Acumulado

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

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

    while (true) {
        const dados = try allocator.alloc(u8, 1_000_000);
        // ERRO: nunca chama allocator.free(dados)
        // Memória vaza a cada iteração até OutOfMemory
        _ = dados;
    }
}
```

### 3. Alocador com Limite Fixo (FixedBufferAllocator)

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

pub fn main() !void {
    var buffer: [64]u8 = undefined;
    var fba = std.heap.FixedBufferAllocator.init(&buffer);
    const allocator = fba.allocator();

    // Pede mais do que os 64 bytes disponíveis
    const dados = try allocator.alloc(u8, 128);
    // error.OutOfMemory — buffer fixo não tem espaço
    defer allocator.free(dados);
}
```

### 4. Crescimento Descontrolado de ArrayList

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

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

    var lista = std.ArrayList(u8).init(allocator);
    defer lista.deinit();

    // Adicionando elementos indefinidamente
    while (true) {
        try lista.append(42);
        // Eventualmente: error.OutOfMemory
    }
}
```

### 5. Recursão que Aloca em Cada Nível

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

fn processarRecursivo(allocator: std.mem.Allocator, profundidade: usize) !void {
    const buffer = try allocator.alloc(u8, 1_000_000);
    defer allocator.free(buffer);

    if (profundidade > 0) {
        // Cada nível de recursão mantém 1 MB alocado
        try processarRecursivo(allocator, profundidade - 1);
    }
}
```

## Como Corrigir

### Solucao 1: Tratar o Erro Explicitamente

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

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

    const buffer = allocator.alloc(u8, 1_000_000) catch |err| {
        std.debug.print("Falha ao alocar memória: {}\n", .{err});
        return;
    };
    defer allocator.free(buffer);

    // Usa buffer normalmente
    buffer[0] = 42;
}
```

### Solucao 2: Liberar Memória Corretamente com defer

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

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

    var lista = std.ArrayList([]u8).init(allocator);
    defer {
        for (lista.items) |item| {
            allocator.free(item);
        }
        lista.deinit();
    }

    var i: usize = 0;
    while (i < 100) : (i += 1) {
        const item = try allocator.alloc(u8, 1024);
        try lista.append(item);
    }
}
```

### Solucao 3: Pré-alocar Capacidade Conhecida

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

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

    // Pré-aloca capacidade para evitar realocações frequentes
    var lista = try std.ArrayList(u32).initCapacity(allocator, 10_000);
    defer lista.deinit();

    var i: u32 = 0;
    while (i < 10_000) : (i += 1) {
        lista.appendAssumeCapacity(i); // Não pode falhar — capacidade já reservada
    }
}
```

### Solucao 4: Usar ArenaAllocator para Alocações Temporárias

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

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

    var arena = std.heap.ArenaAllocator.init(gpa.allocator());
    defer arena.deinit(); // Libera TUDO de uma vez

    const allocator = arena.allocator();

    // Múltiplas alocações sem precisar de free individual
    const a = try allocator.alloc(u8, 1024);
    const b = try allocator.alloc(u8, 2048);
    const c = try allocator.alloc(u8, 4096);
    _ = a;
    _ = b;
    _ = c;
    // Tudo é liberado pelo arena.deinit()
}
```

### Solucao 5: Limitar Tamanho de Alocação

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

const MAX_BUFFER_SIZE = 10 * 1024 * 1024; // 10 MB

fn alocarBuffer(allocator: std.mem.Allocator, tamanho: usize) ![]u8 {
    if (tamanho > MAX_BUFFER_SIZE) {
        return error.TamanhoExcedido;
    }
    return allocator.alloc(u8, tamanho);
}
```

## Diagnóstico com GeneralPurposeAllocator

O `GeneralPurposeAllocator` detecta vazamentos automaticamente:

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

pub fn main() !void {
    var gpa = std.heap.GeneralPurposeAllocator(.{
        .verbose_log = true, // Loga cada alocação/free
    }){};
    defer {
        const status = gpa.deinit();
        if (status == .leak) {
            std.debug.print("AVISO: vazamento de memória detectado!\n", .{});
        }
    }
    const allocator = gpa.allocator();

    const buffer = try allocator.alloc(u8, 100);
    _ = buffer;
    // Sem free — o deinit reportará o vazamento
}
```

## Estratégias de Prevenção

1. **Sempre use `defer` para liberar memória** logo após a alocação.
2. **Prefira alocação na stack** quando o tamanho é conhecido em tempo de compilação.
3. **Use `ArenaAllocator`** para muitas alocações temporárias com o mesmo ciclo de vida.
4. **Valide tamanhos** antes de alocar, especialmente com dados de entrada externa.
5. **Monitore uso de memória** com o `GeneralPurposeAllocator` em modo verbose durante desenvolvimento.

## Erros Relacionados

- [Memory leak detected](/erros/erro-allocator-leak-detected/) — Vazamento de memória detectado pelo alocador
- [Invalid free](/erros/erro-allocator-invalid-free/) — Tentativa de liberar ponteiro inválido
- [Stack overflow](/erros/erro-stack-overflow/) — Estouro da pilha de execução
- [Buffer overrun](/erros/erro-buffer-overrun/) — Acesso além dos limites do buffer

## Links Úteis

- [Documentação oficial do Zig — Allocators](https://ziglang.org/documentation/master/#Choosing-an-Allocator)
- [Receitas de gerenciamento de memória](/receitas/)
- [Tutorial sobre alocadores em Zig](/tutoriais/)
