Hi all. New to Zig and also to languages that require the developer to manually manage memory, so pardon my “noob-ness”.
Hence this post is partly a question and partly asking for confirmation on some assumptions I am making.
So I just finished going through the allocators section of ZigLearn.
The first question I asked myself, after reading that section was, when do one even need to manually allocate memory?
This led me to this StackOverflow answer here where the author mentioned that:
You use
malloc
when you need to allocate objects that must exist beyond the lifetime of execution of the current block (where a copy-on-return would be expensive as well)…
I think a function is a perfect example of a current executing block, this then led me to wonder, if the above is indeed the case, then how useful is the pattern of allocate/free with defer, I just read about?
I ask that because I was thinking of a situation where a function allocates memory and returns it. But if the memory is freed when the memory exits, then that prevents the allocated objects from existing beyond the lifetime of the executing block right?
Then I found the post here How to return an ArrayList after allocate in function? where this very question was asked. Reading the responses I found the way to go is to use errdefer
instead of defer
.
Okay that does sounds like I have the answer to my question. Just that later in the thread it was mentioned that:
It’s generally a code smell to return an ArrayList as the return type of the function. It tends to work out better to accept a mutable ArrayList as a parameter, and have the function append to it.
Okay, I get the rationale for saying returning an ArrayList
is a code smell, but I am now wondering, what if you have found a valid scenario where returning an allocated memory is indeed what you have to do, who then makes sure that the memory handed out by the function actually get freed?
The other thought/question is regarding best practices. Will I be right to say that the pattern then is to always allocate all the memory the program will need in main
and then pass down mutable reference to this memory? Then at the end of main
, a defer
ensures it is cleaned up?
Or there are other ways/patterns to go about this?