First question is, how come de-referencing self.* works when self is not a reference?
Second question is, it looks like this should also lead to a dangling pointer? Given the fact that the memory is allocated in a function and a pointer to it is returned.
allocator.create creates a Self object in heap memory. The object is live until allocator.destroy is called to free the memory. self.* = Self{...} assigns the created Self data to the allocated memory pointed by self.
Will the location always be heap memory when allocator.create is used? for instance if the allocator is a std.heap.FixedBufferAllocator? I looked at the documentation for allocator.create here Zig Documentation and it is not explicit that this would always be heap memory so just wanted to be sure (basically to avoid dangling pointers)
I also see that sometimes allocator.alloc is used instead of allocator.create and this allocates an array instead. Question is when using allocator.alloc are there things to keep in mind when returning the memory it allocates from a function? Basically is there any chances of having a dangling pointer?
Also looking at it’s documentation here Zig Documentation it does not really say if the memory allocated via alloc would be heap allocated or not. How may one be sure of this?
I am not exactly sure what you mean with dangling pointers.
When you allocate something you need to de-allocate it.
When you allocate with alloc you free it with free.
When you allocate with create you free it with destroy.
When you allocate something and you never de-allocate it, then you are leaking memory (which can be fine if your program is about to quit anyway), but by using defer/errdefer well can avoid leaks.
(You also can write tests and use checkAllAllocationFailures)
Normally dangling pointer means that some data structure or piece of code holds on to a pointer that points to a piece of memory that was already freed. This is bad because you shouldn’t keep pointers to memory you don’t own, the allocator will give that memory to some other allocation call and that other piece of code doesn’t want some other part of the code messing with its memory.
If you mean something else with dangling pointer, please clarify.
No, FixedBufferAllocator gives you memory from a buffer with the interface of heap allocation, this is useful because it allows you to write code that is agnostic over whether the memory is on the stack or heap and allows you to use both with the same interface and without any code changes, but if you pass it a FixedBufferAllocator that is too small you will get an error.OutOfMemory because FixedBufferAllocator is limited in size, so you can only use that if failing allocation is okay or you are able to predict a size that is big enough.
There is also StackFallbackAllocator which will fallback to another allocator if it doesn’t fit in the specified size.
It depends on the allocator and you know by reading the documentation and or code of the allocator.
It seems to me like you might have some misconception about memory, heap allocated memory isn’t magical, if you want heap memory you need to use an allocator that gives you heap memory. But sometimes you can use stack memory and it can be beneficial for performance.
It mostly depends on the lifetime of the memory and how big the needed memory is, whether using stack memory is an option.
FixedBufferAllocator returns memory from a buffer, that buffer might be in the stack.
allocator.alloc is used to allocate memory for multiple sequentially located objects (an array). The memory allocated with alloc vs create have no difference except that you need to call free for memory allocated using alloc and destroy for memory allocated using create.
I am talking about the case where value is created within a function and a pointer to it is returned, but it’s lifetime is tied to to function, hence when the function goes out of scope, the reference returned is now garbage.
In that case the term applies (I just didn’t think you were using it in that way for some reason) and in that case you need to use an allocator that gives you heap memory, which requires reading the documentation of the allocator.
But maybe we could get safety checks in the future which would be able to give error messages for these memory bugs, here is a related issue: