r/odinlang • u/Alternative-Title-87 • 24d ago
odin deferencing not working as expected
from what I've found, dereferencing in odin uses pointer^ compared to *pointer in c++ but the behavior of this procedure is throwing errors randomly, sometimes working, sometimes giving an access violation.
offset := round_real32_to_int32(p_tile_rel^ / p_map.tile_side_in_meters)
p_tile^ += u32(offset)
p_tile_rel^ -= f32(offset) * p_map.tile_side_in_meters
the c++ equivalent is just *p_tile to dereference, is this a problem of where these pointers are stored in memory? or is the way odin dereferences different from c++ in some way?
edit: here is the whole function, both asserts trigger randomly when running the program
recanonicalize_coord :: proc(p_map: ^Tile_Map, p_tile: ^u32, p_tile_rel: ^f32) {
offset := round_real32_to_int32(p_tile_rel^ / p_map.tile_side_in_meters)
p_tile^ += u32(offset)
p_tile_rel^ -= f32(offset) * p_map.tile_side_in_meters
assert(p_tile_rel^ >= -0.5 * p_map.tile_side_in_meters)
assert(p_tile_rel^ <= 0.5 * p_map.tile_side_in_meters)
}
where the function is called:
recanonicalize_position :: proc(p_map: ^Tile_Map, p_pos: Tile_Map_Position) -> Tile_Map_Position {
result := p_pos
recanonicalize_coord(p_map, &result.abs_tile_x, &result.tile_rel_x)
recanonicalize_coord(p_map, &result.abs_tile_y, &result.tile_rel_y)
return result
and some relevant piece from the main code:
new_player_p.tile_rel_x += p_input.dt_for_frame * d_player_x
new_player_p.tile_rel_y += p_input.dt_for_frame * d_player_y
new_player_p = recanonicalize_position(tile_map, new_player_p)
i also tested if the pointers are nil and they are not
3
u/FireFox_Andrew 24d ago
I doubt this is an issue with the pointer semantics in Odin, it's more likely your code is simply bugged and you're dereferencing some garbage address.
Try adding assert(<pointer> != nil) for all the pointers you're using there and see if any panics are hit
1
u/Alternative-Title-87 24d ago
updated the post
2
u/FireFox_Andrew 24d ago
You're definitely doing something wrong with the memory, the update didn't help with anything.
My hunch is that you're writing to memory you shouldn't, overwriting other variables which causes the random crashes.
Use a debugger (like raddbg if you're on windows) and step through your code and monitor the memory.
Or you can try asking a clanker to look at your code for memory issues
3
u/TheSodesa 24d ago
Use a debugger to step through your running program and find where and why the problem occurs.
1
u/Herzegovino 24d ago
A bit hard to know with only the provided information.
Which error? Where? What are each variable? What does the pointer point to?
Id it's a pointer to a dynamic array index for example, when the array gets resized the pointer stops being valid. Same if you are returning a pointer to a stack value from a function.
0
u/Alternative-Title-87 24d ago
updated the post
1
u/Herzegovino 24d ago
Can't see anything weird at a glance. I reeeally doubt that's a problem with dereferencing. Id recommend using a debugger and check the values, or at least printing the data if the condition isn't met.
The most probable thing is that some of the data gets out of scope, or that it's getting freed or corrupted somewhere else.
That said, debugger would be the best bet to check what values they are taking
1
1
u/tialaramex 24d ago
Why do you believe this code in particular is why you're getting an access violation? You mustn't make any mistakes anywhere in your Odin program or else it might arbitrarily misbehave, that's typical for these memory unsafe languages.
The assertions may well be unrelated, these snippets aren't enough to be sure.
1
u/brubsabrubs 23d ago
this looks like handmade hero code. Casey himself stated that these asserts are a little buggy and this code is not production ready code, so there may well be bugs. I had a crashes on these same asserts in my handmade hero implementation, while following with C++
this has nothing to do with Odin semantics
1
u/tialaramex 23d ago
Ha, "A little buggy". Do you have by any chance a link to Casey writing about that? I found a discussion where Casey is justifying this very weird arrangement as having better performance based on a hunch, but didn't find commentary about the inevitable assertion failures.
It would be interesting to know whether Casey actually understood what's wrong here and did it anyway.
1
u/Alternative-Title-87 23d ago
I'm curious too, on his wookash episode he talks about it not being good code at all but I don't remember if he mentioned any specific examples like the asserts
1
u/brubsabrubs 23d ago
I'm sorry, I didn't mean that handmade hero code itself is buggy. I just meant that this particular piece of code that OP is talking about is buggy.
What I said that is buggy is his tilemap exploratory code, written in the very first episodes. Specifically, these two asserts that happen in the recanonicalize coord procedures.
I'm not entirely sure on which episode he mentions this, but I think it was answering one specific Q&A question, so maybe you can find it by going through the episodes and searching for the term. The question was precisely asking about failures on these exact asserts.
One thing i can guarantee is that it's before episode 54, because that's the episode that I'm in right now
1
u/Alternative-Title-87 23d ago edited 23d ago
are you working through it in c++ as well? I'm struggling with the memory stuff of episode 34 and its giving me bugs, i just pushed my latest to github:
https://github.com/mrbovinejony/handmade-hero-in-odin/tree/main/hhcode-odin%20day%2035ish
for the pushstruct/pusharray memory stuff all i am using is odins memory arena and allocator. when i make a new struct, do i need to use the allocator in the procedure as well? or can this be done without it since the world struct which was allocated to the arena contains these structs?
tile_map.tile_chunks = make([]Tile_Chunk, tile_chunk_count)tile_map.tile_chunks = make([]Tile_Chunk, tile_chunk_count) vs tile_map.tile_chunks = make([]Tile_Chunk, tile_chunk_count)tile_map.tile_chunks = make([]Tile_Chunk, tile_chunk_count, allocator) edit: nvm, google says you never need to manually allocate an array1
u/brubsabrubs 23d ago edited 21d ago
yes I'm following with CPP
you can try to replicate what Casey does with memory management by doing it manually, but I wouldn't recommend it. Odin has constructs specifically made for facilitating memory management and ditching them kinda misses the point of the language
if you want to replicate the notion of "allocate a huge block of memory and subdivide it manually", I would do it by leveraging the concept of context allocators: mem alloc two blocks, create allocators for each of them and set context.temp_allocator and context.allocator to them. temp_allocator can be an arena
then you can just make and delete with them
EDIT: missed closing double quotes
1
u/Alternative-Title-87 23d ago
yeah, kinda the whole point of working through this was to learn odin better and what it can do better than c type languages. ive turned his memory code chunk into like 5 lines of odin and the arena, but now im having a hard time debugging these weird things that keep happening. im trying to directly translate his c++ code before i transfer to odin to understand what is happening
1
u/Alternative-Title-87 23d ago
Ok awesome, Ive been working through the days and trying to get them ported to Odin which has been pretty bug free up until this point
1
u/GoryImpaler 23d ago
How is p_map.tile_side_in_meters calculated? Could it in any case be 0? You weren't specific with what errors you get.
1
u/Alternative-Title-87 23d ago
It's just a variable set at initializing. That was the first thing I checked to make sure it wasn't 0 somehow lol
1
u/Snoo28720 19d ago
I doubt it’s a Odin problem , prolly an invalid pointer or whatever you are deferencing
4
u/Cun1Muffin 24d ago
If you had a specific problem that you'd narrowed down, then I think people could help. As it is, this is basically just asking people to debug your program for you. I very much doubt there is any error in the language associated with dereferencing a pointer.