Skip to content

Conversation

@pepicrft
Copy link
Owner

@pepicrft pepicrft commented Jan 1, 2026

Summary

The initString function stores borrowed slices, not owned copies. Previously, deinit tried to free these slices, causing crashes when they pointed to string literals, template source, or user data.

This change makes deinit only free container memory (arrays, objects) while leaving string memory management to the caller.

The Problem

var context = Value.initObject(allocator);
try context.object.put("title", Value.initString("Hello"));  // borrowed slice!
context.deinit(allocator);  // CRASH: tries to free "Hello" string literal

The Solution

Users who need owned strings should use allocator.dupe() and manage cleanup with arena allocators:

var arena = std.heap.ArenaAllocator.init(allocator);
defer arena.deinit();

var context = Value.initObject(arena.allocator());
try context.object.put("title", Value.initString(try arena.allocator().dupe(u8, title)));
// No need to call context.deinit() - arena handles everything

The `initString` function stores borrowed slices, not owned copies.
Calling `deinit` previously tried to free these slices, causing crashes
when they pointed to string literals, template source, or user data.

This change makes `deinit` only free container memory (arrays, objects)
while leaving string memory management to the caller. Users who need
owned strings should use `allocator.dupe()` and manage cleanup with
arena allocators.
@pepicrft pepicrft merged commit f930d5e into main Jan 1, 2026
14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants