Reputation: 1649
I have the following zig code (simplified):
const allocator = ...;
const Entry = struct {
name: []u8,
};
fn list() ![]u8 {
var entries = try std.json.parse([]Entry, ...);
defer std.json.parseFree([]Entry, entries, ...);
return entries[0];
}
fn main() !void {
const e = try list();
...
}
Everything is (de)allocated with allocator
.
I'd like to return entries[0]
and recycle everything else. The problem is that parseFree
here recycles everything including entries[0]
so I can't seemingly use this function.
So what's the most effective way to do that without copying? What if Entry
is a big structure and I want to return just one its field, say Entry.name
(and, again, recycle everything else)?
Upvotes: 1
Views: 911
Reputation: 642
The quickest way of achieving what you want is to not use parseFree but instead:
const first = entries[0].name;
for (entries[1..entries.len]) |e| alloc.free(e.name); // frees individual strings
alloc.free(entries); // frees the array of structs
return Entry { .name = first };
This is fairly straightforward but relies on understanding how memory is allocated by std.json and the implementation might one day want to allocate things differently, causing the code above to break.
Because of that, my recommendation would be to just copy the string and only resort to this type of extra complexity once you have demonstrated that avoiding that copy brings perceivable benefits.
Upvotes: 1