Live data from Hacker News

The curious case of a memory leak in a Zig program

iamkroot.github.io

21–30 of 80 posts

Re: The curious case of a memory leak in a Zig program

#21

Suggestion for the blog post author: make a PR to the Zig docs to clarify this if it’s not already.

Will do, I have just been procrastinating too much!

Such linear allocators are not too uncommon in embedded / static allocation context, but one definitely needs to know how they work. So first thought was you didn't read the docs, but docs do not clearly state that behavoour that is ugly (:

Re: The curious case of a memory leak in a Zig program

#22
post #18

Earlier quoted context omitted.

It’s not a invariant is the thing. Transient allocators doing little to nothing on free so you can do all the work at once at end of scope is often what you want , if anything a bump allocator freeing its tip is an optimisation. The issue is not that it behaves this way, it’s that it’s not obvious at first glance that this is a bump allocator.

> a bump allocator freeing its tip is an optimisation That's kinda my point? free is there and does something, but also silently does nothing if you violate a fairly subtle invariant. Kinda the definition of "error-prone", and the whole blog post seems to prove it, as the leak was essentially caused by the author not realizing that free was silently doing nothing. I understand why bump-allocators exist, I'm just sayi…

No, there are contexts where you exactly want this behaviour is what poster above wanted to say, and I agree. But it needs to be well documented.

Re: The curious case of a memory leak in a Zig program

#23
post #18

Earlier quoted context omitted.

It’s not a invariant is the thing. Transient allocators doing little to nothing on free so you can do all the work at once at end of scope is often what you want , if anything a bump allocator freeing its tip is an optimisation. The issue is not that it behaves this way, it’s that it’s not obvious at first glance that this is a bump allocator.

> a bump allocator freeing its tip is an optimisation That's kinda my point? free is there and does something, but also silently does nothing if you violate a fairly subtle invariant. Kinda the definition of "error-prone", and the whole blog post seems to prove it, as the leak was essentially caused by the author not realizing that free was silently doing nothing. I understand why bump-allocators exist, I'm just sayi…

> That's kinda my point?

It’s the exact opposite of your point.

> free is there and does something, but also silently does nothing if you violate a fairly subtle invariant.

Again, not an invariant.

> the leak was essentially caused by the author not realizing that free was silently doing nothing

The leak was caused by the author not knowing this is a bump allocator because that was not clear from the naming (and the documentation is essentially non-existent).

> I'm just saying this particular one's API has quite the footgun.

It’s not the API that’s a footgun, it follows the standard allocator API so it can be used wherever an allocator is expected. If it did not, its usage scope would be extremely limited as you'd only be able to use it for bespoke allocations, and wouldn't be able to use it for allocating e.g. arrays or sets or maps.

Re: The curious case of a memory leak in a Zig program

#25
I know absolutely nothing about Zig (but I know C) and when I read "FixedBufferAllocator" I immediately guessed what the problem would be. I can see why it is claimed as a C replacement.

I am actually kind of surprised the author spent so much time figuring it out. The name of the allocator is not that well-defined, but at least to me it hints of it being simpler rather than full-featured allocator. I would also imagine he's using this in a very anti-patternic way. One would guess the point of this would be to destroy the entire allocator on every iteration, rather than trying to free everything 'nicely' which would be a lot of wasted work. This is a rather common pattern in a lot of "high-level" embedded development like this.

Re: The curious case of a memory leak in a Zig program

#26
post #14

An allocator that silently does nothing on free if you violate one if its invariants (freeing an allocation that wasn't the latest) seems an incredibly error-prone design? It should probably return an error or panic (if free's API allows it, I guess).

It’s not a invariant is the thing. Transient allocators doing little to nothing on free so you can do all the work at once at end of scope is often what you want , if anything a bump allocator freeing its tip is an optimisation. The issue is not that it behaves this way, it’s that it’s not obvious at first glance that this is a bump allocator.

You are entirely correct. If anything, if I were the OP the title of the blog would be "Naming matters - The curious case of ..."

https://docs.rs/bumpalo/latest/bumpalo/

Re: The curious case of a memory leak in a Zig program

#27
post #13

> As a personal challenge, I strived to explicitly limit the amount of memory needed for solving each AoC problem to something that fits on the stack (typically a few MBs at most). If the purpose is to "use limited amount memory" I would suggest to use a GeneralPurposeAllocator and setting "enable_memory_limit" and "requested_memory_limit": https://github.com/ziglang/zig/blob/8f481dfc3c4f12327499485e... . If the purp…

Thanks for the pointers! > use a GeneralPurposeAllocator and setting "enable_memory_limit" and "requested_memory_limit" Interesting! I hadn't looked at GeneralPurposeAllocator too closely, but yes these seem like the right way to do things instead of abusing FixedBufferAllocator as I did. > If the purpose is to "only use the stack"... Not really, I just had to decide on some arbitrary upper bound on the mem usage, an…

>Is there a better way?

Just let the kernel handle it. The virtual memory and mapped memory abstraction the kernel has makes your program's implementation simpler.

Re: The curious case of a memory leak in a Zig program

#28

I know absolutely nothing about Zig (but I know C) and when I read "FixedBufferAllocator" I immediately guessed what the problem would be. I can see why it is claimed as a C replacement. I am actually kind of surprised the author spent so much time figuring it out. The name of the allocator is not that well-defined, but at least to me it hints of it being simpler rather than full-featured allocator. I would also imag…

That's interesting, all it told me is that it's fixed-size. Without more information, and likely as the author did, I'd have assumed something like a bitmap allocator, which is hardly complicated but is a lot "safer" than a bump allocator in the face of deallocations (though it is sensitive to fragmentation).

Re: The curious case of a memory leak in a Zig program

#29

Earlier quoted context omitted.

Will do, I have just been procrastinating too much!

Such linear allocators are not too uncommon in embedded / static allocation context, but one definitely needs to know how they work. So first thought was you didn't read the docs, but docs do not clearly state that behavoour that is ugly (:

> So first thought was you didn't read the docs, but docs do not clearly state that behavoour that is ugly (:

Yep, neither the name nor what little documentation there is a are really helpful, and that looks to be a long-standing issue (https://github.com/ziglang/zig/issues/3049).

Seems to me like this allocator should be renamed something like "FixedBufferBumpAllocator", which:

- leaves room for other fixed-buffer allocators (e.g. bitmap, slabs)

- spell out that there's something of note about the allocator, whose drawbacks the developer either would already be aware of or would be able to look up easily

Post reply on HN