Crystal: Shifting a `Deque(Nil)` more times than its initial capacity crashes the program

Created on 7 Apr 2019  Â·  6Comments  Â·  Source: crystal-lang/crystal

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.

bug compiler

All 6 comments

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"

https://carc.in/#/r/6oci

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
.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

oprypin picture oprypin  Â·  3Comments

will picture will  Â·  3Comments

ArthurZ picture ArthurZ  Â·  3Comments

asterite picture asterite  Â·  3Comments

will picture will  Â·  3Comments