I encountered an "Invalid memory access" error in my project when accessing a local variable inside a closure. I was able to reduce the error the the following example:
struct Foo
getter values = {1, 2, 3, 4}
end
foo = Foo.new
procs = [] of ->
procs.push -> { foo }
procs.first.call # Calling the proc gives the error
Running that gives an "Invalid memory access" error:
Invalid memory access (signal 11) at address 0x0
[0x5653d17eaac6] *Exception::CallStack::print_backtrace:Nil +118 in /home/crystal/.cache/crystal/crystal-run-eval.tmp
[0x5653d17d9586] ~procProc(Int32, Pointer(LibC::SiginfoT), Pointer(Void), Nil) +310 in /home/crystal/.cache/crystal/crystal-run-eval.tmp
[0x7f241f2ab770] ?? +139793118443376 in /usr/lib/libc.so.6
[0x5653d17da126] ~procProc(Foo) +6 in /home/crystal/.cache/crystal/crystal-run-eval.tmp
[0x5653d17c9b2f] __crystal_main +1263 in /home/crystal/.cache/crystal/crystal-run-eval.tmp
[0x5653d188e316] *Crystal::main_user_code<Int32, Pointer(Pointer(UInt8))>:Nil +6 in /home/crystal/.cache/crystal/crystal-run-eval.tmp
[0x5653d188e28a] *Crystal::main<Int32, Pointer(Pointer(UInt8))>:Int32 +58 in /home/crystal/.cache/crystal/crystal-run-eval.tmp
[0x5653d17d7036] main +6 in /home/crystal/.cache/crystal/crystal-run-eval.tmp
[0x7f241f294cd0] ?? +139793118350544 in /usr/lib/libc.so.6
[0x7f241f294d8a] __libc_start_main +138 in /usr/lib/libc.so.6
[0x5653d17c9565] _start +37 in /home/crystal/.cache/crystal/crystal-run-eval.tmp
[0x0] ???
I assume this has to do with foo not being available anymore from inside the closure.
But this error only seems to happen under specific circumstances. Making any of the following (seemingly unrelated) changes to the codes fixes the error.
Making @values a tuple of size 3 works (getter values = {1, 2, 3})
Making Foo a class instead of a struct works (class Foo)
Initializing the procs array in 1 line instead of 2 lines works (procs = [-> { foo }])
Calling a method on foo.values inside the closure works: (procs.push -> { foo.values.last }). However, calling only foo.values doesn't work.
Printing the values inside the closure works (procs.push -> { puts foo }). However, pp foo doesn't work.
I was able to eventually fix the error in my project by making some of these small changes. But this error should not happen in the first place, since as far as I can tell the code is valid.
I encountered an "Invalid memory access" error in my project when accessing a local variable inside a closure. I was able to reduce the error the the following example:
https://play.crystal-lang.org/#/r/gtgl
Running that gives an "Invalid memory access" error:
I assume this has to do with
foo
not being available anymore from inside the closure.But this error only seems to happen under specific circumstances. Making any of the following (seemingly unrelated) changes to the codes fixes the error.
@values
a tuple of size 3 works (getter values = {1, 2, 3}
)Foo
a class instead of a struct works (class Foo
)procs
array in 1 line instead of 2 lines works (procs = [-> { foo }]
)procs.push -> { foo.values.last }
). However, calling onlyfoo.values
doesn't work.procs.push -> { puts foo }
). However,pp foo
doesn't work.I was able to eventually fix the error in my project by making some of these small changes. But this error should not happen in the first place, since as far as I can tell the code is valid.