# Fixed-Buffer Allocator

### Fixed-Buffer Allocator

A fixed-buffer allocator uses memory that already exists.

It does not request memory from the operating system. Instead, allocations come from a fixed block supplied by the program.

This is useful in embedded systems, kernels, bootloaders, games, temporary workspaces, and programs that must avoid heap allocation.

A fixed-buffer allocator begins with a buffer:

```zig
var buffer: [1024]u8 = undefined;
```

The allocator uses this memory for future allocations.

A complete example:

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

pub fn main() !void {
    var memory: [1024]u8 = undefined;

    var fba = std.heap.FixedBufferAllocator.init(&memory);
    const allocator = fba.allocator();

    const bytes = try allocator.alloc(u8, 128);

    @memset(bytes, 0);

    std.debug.print("allocated {d} bytes\n", .{bytes.len});
}
```

The memory comes from:

```zig
var memory: [1024]u8 = undefined;
```

The allocator state is:

```zig
var fba = std.heap.FixedBufferAllocator.init(&memory);
```

The allocator interface is:

```zig
const allocator = fba.allocator();
```

Unlike the page allocator or general-purpose allocator, the fixed-buffer allocator cannot grow beyond its buffer.

If the buffer is exhausted, allocation fails:

```zig
const xs = try allocator.alloc(u8, 5000);
```

This may return `error.OutOfMemory`.

The allocator therefore behaves predictably. The program knows the exact maximum memory available to the allocator.

This is often important in constrained systems.

The fixed-buffer allocator also avoids operating-system allocation overhead. Allocation is usually very fast because the allocator only advances through the buffer.

A common use is temporary workspace memory:

```zig
var workspace: [4096]u8 = undefined;

var fba = std.heap.FixedBufferAllocator.init(&workspace);
const allocator = fba.allocator();
```

Functions can now allocate temporary objects without touching the system heap.

A fixed-buffer allocator is often combined with containers:

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

pub fn main() !void {
    var memory: [256]u8 = undefined;

    var fba = std.heap.FixedBufferAllocator.init(&memory);
    const allocator = fba.allocator();

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

    try list.appendSlice("hello");
    try list.appendSlice(" zig");

    std.debug.print("{s}\n", .{list.items});
}
```

If the list grows beyond the available buffer, allocation fails.

This failure is explicit.

A fixed-buffer allocator is therefore useful for testing allocation behavior under strict limits.

For example:

```zig
var memory: [64]u8 = undefined;
```

Now large allocations fail quickly, which may expose assumptions hidden in the program.

The allocator itself does not own the buffer. The buffer must outlive all allocations made from it.

This is wrong:

```zig
fn makeAllocator() std.mem.Allocator {
    var memory: [1024]u8 = undefined;

    var fba = std.heap.FixedBufferAllocator.init(&memory);

    return fba.allocator(); // wrong
}
```

The returned allocator depends on `memory` and `fba`, both of which disappear when the function returns.

The backing storage must remain valid.

The fixed-buffer allocator usually works best when:

- maximum memory usage is known
- allocations are temporary
- allocation speed matters
- heap allocation is undesirable
- deterministic memory usage is required

It works poorly when memory requirements are unpredictable or very large.

Unlike a general-purpose allocator, a fixed-buffer allocator cannot request more memory when exhausted.

The simple model is:

```text
buffer -> allocator -> allocations
```

The allocator divides the buffer into pieces until no space remains.

Exercises:

Exercise 12-17. Create a fixed-buffer allocator backed by a 512-byte array and allocate two slices from it.

Exercise 12-18. Use `std.ArrayList(u8)` with a fixed-buffer allocator and append a short string.

Exercise 12-19. Create a very small fixed buffer and observe allocation failure.

Exercise 12-20. Explain why a fixed-buffer allocator is useful in embedded systems.

