I'm having a Deque with initial capacity of N and try to push N + 1 values to read and then read them one-by-one.
This simple program works as expected (https://carc.in/#/r/6obc):
deque = Deque(Bool).new(1)
2.times do
deque << true
end
2.times do
deque.shift
end
puts "ok"
Howerver, if using Nil as the deque's type, it crashes (https://carc.in/#/r/6obd):
deque = Deque(Nil).new(1)
2.times do
deque << nil
end
2.times do
deque.shift
end
puts "ok"
Invalid memory access (signal 11) at address 0x0
The last offending line I've found is this — Pointer(Nil).realloc may lead to the bug. The issue happens with Nil only. Other types, as well as custom structs and classes, work as expected.
Fails with empty struct too:
record A
deque = Deque(A).new(1)
2.times do
deque << A.new
end
2.times do
deque.shift
end
puts "ok"
Also fails if you replace Deque with Array
This is fixed when adding check_needs_resize to Array's shift and increase_capacity if @size >= @capacity to Deque's shift but it's still strange that it happens only with Nil and an empty struct.
The problem seems to be that the @buffer of Nil or an empty struct is a null pointer internally: https://carc.in/#/r/6of0.
@r00ster91 yes, the problem is that they have zero size, so array needs buffer of size 0 and that's ok.
Allocating of 0 bytes returns null pointer, and that's ok too (we aren't going to write anything to a buffer).
But all remaining code have to take this case into account (explicitly or implicitly).
Not sure if Crystal handles this explicitly, but it's worth noting that
from a malloc standpoint, allocating 0 bytes doesn't have to return a
null value; it's valid to return e.g. a special memory address signifying a
0 byte allocation.
--
Ryan (ライアン)
Yoko Shimomura, ryo (supercell/EGOIST), Hiroyuki Sawano >> everyone else
https://refi64.com/
On Sun, Apr 7, 2019, 12:43 PM kipar notifications@github.com wrote:
@r00ster91 https://github.com/r00ster91 yes, the problem is that they
have zero size, so array needs buffer of size 0 and that's ok.
Allocating of 0 bytes returns null pointer, and that's ok too (we aren't
going to write anything to a buffer).
But all remaining code have to take this case into account (explicitly or
implicitly).—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
https://github.com/crystal-lang/crystal/issues/7644#issuecomment-480613484,
or mute the thread
https://github.com/notifications/unsubscribe-auth/ABnMSU1L8aDC3PMsXEcdwKbbqFqFv8m2ks5vei40gaJpZM4cgvj5
.