Skip to content

Memory Management โ€‹

What you'll learn โ€‹

  • Exactly who owns every allocation and when to call deinit.

The rules โ€‹

Client owns an allocator (e.g. std.heap.DebugAllocator)
Parser.init(allocator) borrows it for the parser lifetime
parseString copies source bytes into the new Tree
Tree owns its node pool, child index buffer, and source copy
tree.cursor() / parser.queryCursor() inherit the stored allocator
Every deinit releases exactly what its object owns
  1. Parser owns its stacks, scratch buffers, candidate lists, and range list. deinit frees them all.
  2. Tree owns its source copy, node pool, and child-index buffer. Nodes and cursors borrow the tree โ€” never use them after tree.deinit().
  3. Node owns nothing. It is two words (tree pointer + index).
  4. TreeCursor owns its path stack only.
  5. Query owns compiled patterns, captures, and predicate args. QueryCursor owns its match lists.
  6. Changed-range slices are owned by the caller and freed with freeChangedRanges (or tree.freeChangedRanges).

No leaks, no hidden state โ€‹

There are no global allocators, no global parsers, and no hidden I/O. Two parsers in different threads never share memory (parsers are not internally synchronized โ€” use one parser per thread; see FAQ).

API used โ€‹

Released under the MIT License.