crystal 堆指针总是偶数吗?

Are crystal heap pointers always even?

我试过这段代码:

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 或 [=17 的倍数=].