3 ms·
Arena can be used to allocate many times but deallocate exactly once. In Zig: test "arena allocator" { var arena = std.heap.ArenaAllocator.init(std
by d0mine 2y ago
Arena can be used to allocate many times but deallocate exactly once. In Zig:
test "arena allocator" {
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
defer arena.deinit();
const allocator = arena.allocator();
_ = try allocator.alloc(u8, 1);
_ = try allocator.alloc(u8, 10);
_ = try allocator.alloc(u8, 100);
}
- jay-barronville 2y agoI’m a fan of Zig, but I just want to point out that creating dedicated allocators for managing specific regions/chunks of memory or memory within specific application scopes (i.e., arenas) is just another memory allocation strategy rather than the ultimate solution to memory management issues. It comes with its own trade-offs and depends entirely on your use case. Also, it’s great that Zig has this battery included in its standard library, but arenas aren’t unique to Zig nor are they difficult to implement in any language that allows manual memory management. I’m just pointing this out because I keep seeing folks highlight this as a key feature of Zig over C.
- anymouse123456 2y agoThis. I've been loving Zig for some years now, but still write a lot of embedded C at work. I've started to use simple memory arenas in C and it just feels so damn _nice_. There's basically a shared lifetime for most of my transient allocations, which are nicely bounded in time by a "frame" of execution. Malloc/Free felt like a crazy amount of work, whereas an arena_reset(&ctx) just moves a pointer back to the first entry. Another person pointed out that arenas are not destructors, and this is a great point to make. If you're dealing with external resources, moving an arena index back to the beginning does not help - at all.
- OskarS 2y agoYou can do it in C for sure, but "culturally" in C, there's a stateless global allocator called "malloc", which is not the case in Zig. For instance, if you have a library libsomething in C, it will at most (probably) have something like this: #ifndef LIB_MALLOC #define LIB_MALLOC malloc #end if it allows you to customize allocation strategy at all, which is not a given. But this only allows you at compile time to provide your own stateless global allocator. This is very different in Zig, which has a very strong culture of "if something needs to allocate memory, you pass it a stateful, dynamically dispatched allocator as an argument". You COULD do that in C, but virtually nobody does.
- samatman 2y agoIt's 100% a key feature of Zig. Culturally, if it allocates, then it takes an allocator as an argument. C simply doesn't work that way. You could write C that way, but people don't. I've written reasonable amounts of both, and it's just different. For instance, in Zig, you can create a HashMap using a FixedBufferAllocator, which is a region of memory (which can be stack allocated) dressed up as an allocator. You can also pass it an arena and free all at once, or any other allocator in the standard library, or implemented by you, or anyone else. Show me a C library with a HashMap which can do all three of these things. Everything which allocates takes an allocator, third-party libraries respect this convention or will quickly get an issue or PR either requesting or implementing this convention. Ultimate solution? No, but also, sort of. The ability to idiomatically build a fine-grained memory policy is a large portion of what makes Zig so pleasant to use.
- sixthDot 2y agoallocation is not construction, and deallocation is not destruction. The two steps are oftently executed sequentially but if you think that they are the same you'll end up with leaks, e.g at the level of the operating system (e.g GDI handles). What I mean is that arena allocators are not as simple as you pretend. That depends on what they allocate. The more commonly reason why arena allocators are praised is the cache locality.