| name | zig-memory-safety |
| description | Zig memory-safety review and implementation workflow for coding agents. Use when writing, reviewing, debugging, or refactoring Zig code that touches allocators, ownership, lifetimes, slices, pointers, arenas, unsafe casts, parser buffers, FFI buffers, leak detection, double-free/use-after-free risks, safety-checked illegal behavior, ReleaseFast safety assumptions, or Zig 0.15/0.16 memory API drift. |
Zig Memory Safety
Operating Mode
Use this skill as a defect-finding workflow, not a generic Zig tutorial. Start by proving the active toolchain and project pin:
zig version
test -f build.zig.zon && sed -n '1,120p' build.zig.zon
As of 2026-05-13, Zig 0.16.0 is the latest tagged release and 0.17.0-dev builds are available upstream. Many production repos remain pinned to 0.15.x; follow the repo pin unless the task is explicitly a migration.
Memory Model
- Treat every allocation as a contract with one owner, one deinit/free path, and clear transfer semantics.
- Prefer passing
std.mem.Allocator explicitly at construction boundaries. Avoid hidden globals and allocator selection inside low-level helpers.
- Distinguish borrowed slices from owned buffers in names, docs, tests, and deinit behavior.
- Do not return slices or pointers into stack locals, temporary parser buffers, freed environment buffers, arena memory that dies before the caller, or reallocated containers.
- Use arenas only for bounded request/session lifetimes. In long-running loops, reset or deinit per iteration so arenas do not hide leaks.
- Prefer slices over many-item pointers because slices carry length and normal indexing is bounds-checked in safety-enabled modes. Treat slices as borrowed pointer-plus-length views, not owners.
- Treat
ArrayList.items and similar container slices as invalidated after resize, append, deinit, or transfer.