Anon12/02/25, 10:27No.107404903
With the "linear allocator that releases all memory at once" I always run into issues:- Overlapping lifetimes
Imagine you want to read a png file, decode the bytes, then free the original raw png bytes, but keep the decoded bytes. Then you can't free the raw png bytes. You have two options here.
Either just don't free, but that's like saying, I don't do memory management at all here. Could be fine if you have enough memory, but that just sidesteps the problem.
Or you have to pass in two allocators, e.g. one for temporary allocation, one for permanent ones you want to keep. That's only a little annoying in this scenario, and it's pretty clear what's temporary and what's permanent, but I always run into situations where I suddenly have to route a second arena down a bunch of calls or create a new one ad-hoc just to get some memory, and it gets messy quickly.- Growing data structures
Dynamic arrays are just so useful, but if you only have a linear allocator, you can only allocate at the top, you can only dynamically grow something if it happens to be the very last thing you allocated which is never the case in non-trivial situations. In the general case, you're just leaving the old memory behind. With a growth factor of 2, you'd end up needing twice as much memory for your array because of that fragmentation.
That's fine again if you have enough memory, but my point is that arena's just suck for this kind of allocation pattern. Regular allocators handle it fine.
And if you're starting to think about adding a list of free blocks to your linear arena that can hold the blocks that some other data structure grew out of, then you're essentially writing a bad general purpose allocator ad-hoc in your arena. Might as well use a generic malloc then.Sometimes there's clear scenarios where you're just allocating a bunch of stuff linearly, and then linear allocators are obviously great. But trying to force them into all other cases seems like a bad idea.