我试过这段代码:
GC.disable
class A
end
a = [] of UInt64
10000000.times do
tmp = A.new.as(Void*).address
tmp %= 10
a << tmp if !a.includes? tmp
end
puts a.sort
它向我返回了[0_u64, 2_u64, 4_u64, 6_u64, 8_u64]
,这意味着所有的指针地址都是偶数。
堆指针地址是否总是在 Crystal 中偶数?如果是,为什么(是否有任何解释(?
假设所有实例都是连续分配的,则每个指针必须(至少(与前一个指针分开,以分配的内存大小。 您可以获取带有instance_sizeof(A)
的A
实例的大小,在本例中为4
字节。因此,忽略任何填充,所有内存地址都是4
的倍数,并且此系列中每个数字的最后一位是偶数。
不过,这并不是唯一的原因。
如果在堆上分配内存,则malloc
实现需要分配可用内存的地址,甚至可能存储有关该内存分配的一些内部数据。此实现通常遵循一些分配地址的规则。
例如,在 glibc 中,malloc
分配的所有内存地址都是8
(32 位(或16
(64 位(的倍数(请参阅 http://www.delorie.com/gnu/docs/glibc/libc_31.html(。 这当然是特定于系统的,其他实现可能有不同的规则。
所以在你的例子中,假设它与glibc一起使用,即使A
的实例大小为10
,地址仍然是8
或16
的倍数。