---
title: "Como Usar FixedBufferAllocator em Zig"
url: "https://ziglang.com.br/receitas/como-usar-fixedbufferallocator-em-zig/"
markdown_url: "https://ziglang.com.br/receitas/como-usar-fixedbufferallocator-em-zig.MD"
description: "Aprenda a usar FixedBufferAllocator em Zig para alocação de memória sem heap, usando buffers fixos na stack ou em segmento estático."
date: "2026-02-21"
author: "Zig Brasil"
---

# Como Usar FixedBufferAllocator em Zig

Aprenda a usar FixedBufferAllocator em Zig para alocação de memória sem heap, usando buffers fixos na stack ou em segmento estático.


## Introdução

O `FixedBufferAllocator` permite alocar memória a partir de um buffer pré-existente, sem recorrer ao heap. Isso é particularmente útil em sistemas embarcados, código com restrições de tempo real, ou quando você quer garantir que nenhuma alocação de heap aconteça.

Nesta receita, você aprenderá a usar o FixedBufferAllocator para diversas situações práticas.

## Pré-requisitos

- Zig instalado (versão 0.13+). Veja o [guia de instalação](/tutoriais/como-instalar-zig/)
- Conhecimento básico de Zig. Consulte a [introdução ao Zig](/tutoriais/introducao-ao-zig/)

## Uso Básico

Alocar memória a partir de um buffer na stack:

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

pub fn main() !void {
    // Buffer fixo na stack
    var buffer: [1024]u8 = undefined;
    var fba = std.heap.FixedBufferAllocator.init(&buffer);
    const allocator = fba.allocator();

    // Alocar como qualquer outro alocador
    const dados = try allocator.alloc(u8, 100);
    @memset(dados, 'Z');

    const numeros = try allocator.alloc(i32, 10);
    for (numeros, 0..) |*n, i| {
        n.* = @intCast(i * i);
    }

    std.debug.print("String: {s}\n", .{dados[0..3]});
    std.debug.print("Números: ", .{});
    for (numeros) |n| std.debug.print("{d} ", .{n});
    std.debug.print("\n", .{});

    // Verificar espaço restante
    std.debug.print("Buffer total: {d} bytes\n", .{buffer.len});
    std.debug.print("Posição atual: {d} bytes usados\n", .{fba.end_index});
}
```

## Formatar Strings sem Heap

Use FixedBufferAllocator para formatar strings sem alocação dinâmica:

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

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

    const nome = "Maria";
    const idade: u32 = 28;

    const mensagem = try std.fmt.allocPrint(
        allocator,
        "Olá, {s}! Você tem {d} anos.",
        .{ nome, idade },
    );

    std.debug.print("{s}\n", .{mensagem});
    std.debug.print("Usados {d} de {d} bytes\n", .{ mensagem.len, buffer.len });

    // Reset para reutilizar o buffer
    fba.reset();

    const outra = try std.fmt.allocPrint(
        allocator,
        "Temperatura: {d:.1}°C",
        .{23.5},
    );
    std.debug.print("{s}\n", .{outra});
}
```

## Tratar Falta de Espaço

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

pub fn main() !void {
    // Buffer pequeno para demonstrar o limite
    var buffer: [64]u8 = undefined;
    var fba = std.heap.FixedBufferAllocator.init(&buffer);
    const allocator = fba.allocator();

    // Primeira alocação: sucesso
    const a = try allocator.alloc(u8, 30);
    std.debug.print("Alocação 1: {d} bytes (OK)\n", .{a.len});

    // Segunda alocação: sucesso
    const b = try allocator.alloc(u8, 20);
    std.debug.print("Alocação 2: {d} bytes (OK)\n", .{b.len});

    // Terceira alocação: sem espaço
    const c = allocator.alloc(u8, 30);
    if (c) |dados| {
        std.debug.print("Alocação 3: {d} bytes (OK)\n", .{dados.len});
    } else |err| {
        std.debug.print("Alocação 3: falhou com {}\n", .{err});
    }
}
```

## FixedBufferAllocator com ArrayList

Usar estruturas padrão sem heap:

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

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

    // ArrayList usando buffer fixo
    var lista = std.ArrayList(i32).init(allocator);
    // Não precisa de defer deinit -- o buffer é na stack

    for (0..20) |i| {
        lista.append(@intCast(i * 3)) catch |err| {
            std.debug.print("Parou no elemento {d}: {}\n", .{ i, err });
            break;
        };
    }

    std.debug.print("Elementos na lista: {d}\n", .{lista.items.len});
    std.debug.print("Lista: ", .{});
    for (lista.items) |n| std.debug.print("{d} ", .{n});
    std.debug.print("\n", .{});
}
```

## Padrão: Tentar Stack, Fallback para Heap

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

fn processarDados(allocator: std.mem.Allocator, tamanho: usize) ![]u8 {
    const dados = try allocator.alloc(u8, tamanho);
    for (dados, 0..) |*b, i| {
        b.* = @intCast(i % 256);
    }
    return dados;
}

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

    // Tentar com buffer fixo para dados pequenos
    var buffer: [1024]u8 = undefined;
    var fba = std.heap.FixedBufferAllocator.init(&buffer);

    const tamanho: usize = 500;

    if (processarDados(fba.allocator(), tamanho)) |dados| {
        std.debug.print("Processado na stack: {d} bytes\n", .{dados.len});
    } else |_| {
        // Fallback para heap se o buffer fixo não for suficiente
        const dados = try processarDados(gpa.allocator(), tamanho);
        defer gpa.allocator().free(dados);
        std.debug.print("Processado no heap: {d} bytes\n", .{dados.len});
    }
}
```

## Dicas e Boas Práticas

1. **Tamanho do buffer**: Considere o alinhamento de memória. O FBA alinha alocações, então o espaço útil pode ser menor que o tamanho do buffer.

2. **Use `reset()` para reutilizar**: Após processar, faça `fba.reset()` para reaproveitar o buffer sem realocar.

3. **Free não libera no meio**: O FixedBufferAllocator não suporta liberação individual eficiente. Use `reset()` para liberar tudo.

4. **Ideal para dados temporários**: Perfeito quando os dados não precisam sobreviver além do escopo da função.

5. **Combine com ArenaAllocator**: `ArenaAllocator.init(fba.allocator())` dá o melhor dos dois mundos.

## Receitas Relacionadas

- [Usando ArenaAllocator](/receitas/zig-arena-allocator/) - Alocação em lote
- [Usando GeneralPurposeAllocator](/receitas/zig-general-purpose-allocator/) - Alocador de uso geral
- [Detectar Vazamentos de Memória](/receitas/zig-detectar-memory-leak/) - Debug de memória
- [Formatar Strings com std.fmt](/receitas/zig-formatar-string/) - Formatação de texto

## Tutoriais Relacionados

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