I been trying to follow the Crystal specification. It shows an example of taking the address of an instance variable. So I have an analogue function, but pointing to an instance of a 2d array
def map_ptr(x : Int32, y : Int32)
pointerof(@map[x][y])
end
where the @map array is defined somehow similar to:
@map = Array(Array(Room)).new(SIZE) { Array(Room).new(SIZE, Room.new) }
(0...SIZE).each do |x|
(0...SIZE).each do |y|
room_type = ROOMS.sample
@map[x][y] = Room.new(room_type)
end
end
When I try to use the map_ptr function in a assignment like: current_room = map_ptr(0, 0), the Crystal compiler gives me an error that says only:
Error: can't take address of @map[x][y]
Why does it say @map[x][y] and not Room, which is the actual type it should point to? And what am I doing wrong here?
@map[x][y]is a call toArray#[]. You're trying to take the pointer address of its return value. That value is never assigned anywhere, so it doesn't have an address.I assume you actually want to get the address of the element
x, yinside the@maparray. First of all, you should be aware that this is an unsafe operation.Arraycan reallocate its items, so pointers inside it can be invalidated when adding items. If you don't intent to add items, perhaps it would be better useSliceinstead because that has more stability guarantees.Both
ArrayandSlicehave a#to_unsafemethod which returns a pointer to the first item. Then it's just@map.to_unsafe[x].to_unsafe + yto get a pointer inside the second dimension.Example with
Slice: