#Returning an array from a function messes up with the data in the array
1 messages · Page 1 of 1 (latest)
vertices := []Vertex{
//front face
{{0.0, 1.0, 1.0}, {1.0, 0.0, 0.0, 0.75}},
{{0.0, 0.0, 1.0}, {1.0, 1.0, 0.0, 0.75}},
{{1.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 0.75}},
{{1.0, 1.0, 1.0}, {0.0, 0.0, 1.0, 0.75}},
//back face
{{1.0, 1.0, 0.0}, {1.0, 0.0, 0.0, 0.75}},
{{1.0, 0.0, 0.0}, {1.0, 1.0, 0.0, 0.75}},
{{0.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.75}},
{{0.0, 1.0, 0.0}, {0.0, 0.0, 1.0, 0.75}},
//right face
{{1.0, 1.0, 1.0}, {1.0, 0.0, 0.0, 0.75}},
{{1.0, 0.0, 1.0}, {1.0, 1.0, 0.0, 0.75}},
{{1.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.75}},
{{1.0, 1.0, 0.0}, {0.0, 0.0, 1.0, 0.75}},
//left face
{{0.0, 1.0, 0.0}, {1.0, 0.0, 0.0, 0.75}},
{{0.0, 0.0, 0.0}, {1.0, 1.0, 0.0, 0.75}},
{{0.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 0.75}},
{{0.0, 1.0, 1.0}, {0.0, 0.0, 1.0, 0.75}},
//top face
{{0.0, 1.0, 0.0}, {1.0, 0.0, 0.0, 0.75}},
{{0.0, 1.0, 1.0}, {1.0, 1.0, 0.0, 0.75}},
{{1.0, 1.0, 1.0}, {0.0, 1.0, 0.0, 0.75}},
{{1.0, 1.0, 0.0}, {0.0, 0.0, 1.0, 0.75}},
//bottom face
{{0.0, 0.0, 1.0}, {1.0, 1.0, 0.0, 0.75}},
{{0.0, 0.0, 0.0}, {1.0, 0.0, 0.0, 0.75}},
{{1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.75}},
{{1.0, 0.0, 1.0}, {0.0, 1.0, 0.0, 0.75}},
}
return vertices
}```
for vertex in vertices{
fmt.println(vertex)
}```
I learned today that a slice literal is in the stack, so the values don't survive outside of that proc
Yep - that's not an array, but a slice.
And slice literals - as you have there - are equivalent to declaring a stack array, and then slicing it.
soooo, what can I do? I added size to the slices in hopes that I would change them into an array an the data wouldn't be erased after closing the function scope but that still doesn't work
I guess you need to put the values in the heap one way or the other
@static vertices:[?]Vertex={...}
return vertices[:]
something like that maybe?
alright, it does work. Just one question, what does @static do or mean?
the same as in C, makes the object persist (i.e. its not in the stack)
normal array would still be in the stack and die when the proc returns
I would assume though that if you return an array with a size, then that would work? Did you say that also does not work
yup, it does not work (I'm pretty sure, but I gonna check once again in a sec)
It just didn't compile for me because a few lines after I was calling raw_data on vertices and it doesn't work on normal arrays
Returning []Vertex is the issue ultimately, because slices point somewhere
Arrays do not, so if you returned [24]Vertex, then that should be fine.
But yes - @static basically makes it a global variable - it's not a different one per call, it's a single global that is namespaced to the proc.
Allocating is the go-to choice in situations like this - but returning an array can be useful if the size is always known statically - like a hash digest size or whatever.
Even then though, it's not very often used.
Well, I decided to use a dynamic array since I'm gonna add stuff to that thing. And just to be clear, when I finish using it I have to free the memory by calling delete() and now the memory will be fine, right (I'm just asking cuz I haven't used any language when I have to manage the memory:P)
Dynamic arrays use dynamic allocation - which you generally want to free, yeah.
I will head you off a little bit here --- though it applies to dynamic arrays a little less --- is that in MMM land where you manage memory yourself, you generally want to be thinking in terms of batched-up allocations, and not single allocations or objects.
So, [for example,] instead of allocating 150 single things, and then doing a for loop to free them all, you'd use an arena - or some other allocator, depending on how you're using them.
If you're allocating a lot of strings, you might make an arena just for all the strings - etc.
mhm, I wanna spend a bit more time with Odin to understand how that stuff works. I guess watching/reading stuff related to that but for C should be pretty easily transferable to Odin, right?
Dynamic arrays use dynamic allocation
Anything youmake, needs adelete- and anything younewneeds afree, generally-speaking.
Right - the only real differences between Odin and C is:
- Syntax (obviously)
- Context system for dependency injection of common stuff, like logger, allocator, and temp allocator.
- Custom allocators for making allocation more tunable to what you're doing, and making procs that allocate more flexible.
(And faster.)
- Basic datastructures have builtin versions for general purpose usage. (e.g dynamic arrays)
umm, alright, thanks a lot for the help!
Welcome o7
Rickard Andersson made a video talking about it so I might check it out cuz it seemed pretty nice
make([]T, n) is generally the equivalent to (*T)malloc(sizeof(T) * n), incidentally.
Of course, that gives a slice instead of a pointer -- but a slice is basically just a pointer with a length anyway.
The context is a fairly interesting part of Odin.
It's basically just a copy-on-write struct which is passed down the call stack by pointer.
You can find it's definition in core/runtime/core.odin (Context).
It really is just to save you having to pass all the things it has through explicitly, and it means you only really need to think about allocators when you actually want to allocate.
Similar deal with a logger.
Procs that want to allocate or log can basically just reach for the one in the context and use that, with the assumption that the caller has set it to whatever they want it to use.
Feel free to ask away if you have questions. 👍
alrighty, again thanks a lot ♥️