Always ask yourself: who owns the memory behind input and how long it lives?
When you receive a []const u8 parameter, you’re getting a slice, which is just a pointer + length. You have no idea where that pointer points to.
Example:
So if store_input just returns input directly:
The caller gets back a slice pointing to memory they already own and may free or invalidate at any time. If you store that returned slice somewhere and access it later, it’s a dangling pointer. Classic use-after-free.
By doing allocator.dupe(u8, input) instead:
… you’re allocating new memory on the heap, copying the bytes from input into it, and returning a pointer to that. Now the returned slice is completely independent of whatever the caller passed in. Its lifetime is controlled by whoever holds the allocator and decides to free it, typically the caller, after they’re done with it:
The key mental model is: a []const u8 parameter is a borrowed view, not owned data. If you need to outlive the borrow, you must make your own copy.
AdP