Register
Handmade Hero»Forums»Code»Memory allocation/de-allocation
4 posts
Memory allocation/de-allocation
4 months ago Edited by CodyCoderson on May 24, 2020, 12:52 p.m. Reason: Initial post
I'm trying to understand how Casey handles memory. I've only seen the first 60 or so videos, and the source code is too over my head for me to just jump into and figure out for myself, though I've tried.

Can someone explain, possibly with some simple examples, of how Casey would allocate and de-allocate something in handmade hero?

Something simple like, like a linked list. Instead of calling m/calloc when creating a link and free on deletion, what would Casey do?

PushStruct and PushArray seem fairly straightforward, but how would he ever remove something from the arena?
Simon Anciaux
881 posts
Memory allocation/de-allocation
4 months ago
CodyCoderson
Can someone explain, possibly with some simple examples, of how Casey would allocate and de-allocate something in handmade hero?


This depends on the task or system. There isn't a single way to handle memory in handmade hero.

The base is the memory arena. A block of memory where you only push things on. You can have several with different life time (e.g.: the life time of the app, a frame, the duration of a function...) and they are reset after that lifetime (the variable tracking how much memory is used is set back to 0) and a new cycles begin.

If you want at some point pop something from the top of the stack, you can use BeginTempMemory/EndTempMemory. That is mostly keeping track of the size pushed on the arena when you call BeginTempMemory and restoring it when you call EndTempMemory. So you can "free" part of the stack, but always from some point, to the end of the stack (there are no "holes" in the stack).

If you need to be able to remove things in the middle, you probably want to use a different allocator. For example a free list: when you allocate an element you check to see if there is an free element in the list (I assume all elements have the same size here to keep it simple, but it's not necessary); if there is one you use it, if there isn't you allocate a new element (this allocator can be backed by an arena in which case it's just a push, or an array in which case it's just accessing the element, or ... ); When you free an element you add it to the start of the free element list. List here is a link list (single or double link depending on what is needed). So if you allocate 10 elements and free 9 elements you still use memory for 10 elements, unless you decide to spend some time to free the memory at the lower level.

At some point, Casey changed arenas to be growing arenas. You start by allocating a block (to make it simple it's an arena) of a certain size (let's say 1 MB). You push things onto it. When you reach the end of the block, the next allocation will allocate a new block, which is 1 MB or the size requested if it's bigger than 1 MB. The blocks are linked together. When you free memory (from the end of the block since it's an arena), if the arena is empty (size used is 0), the block will be added to a free list to be reused if necessary on following allocations. Instead of adding it to the free list it could be completely freed (VirtualFree) but since it's likely to be reused later it a good idea to keep it in the free list.
4 posts
Memory allocation/de-allocation
4 months ago
That was very helpful, thanks