水晶堆指针是否总是偶数?

时间:2018-08-22 13:37:17

标签: pointers crystal-lang

我尝试了以下代码:

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中吗?如果是,为什么(对此是否有任何解释)?

1 个答案:

答案 0 :(得分:3)

假设所有实例都是连续分配的,则每个指针必须(至少)与前一个指针相距已分配的内存大小。 您可以使用A获得instance_sizeof(A)实例的大小,在这种情况下为4个字节。因此,忽略任何填充,所有内存地址都是4的倍数,并且该系列中每个数字的最后一位是偶数。


但这不是唯一的原因。

如果在堆上分配内存,则malloc实现需要分配一个空闲内存地址,甚至可能存储一些有关该内存分配的内部数据。此实现通常遵循一些分配地址的规则。

例如,在glibc中,由malloc分配的所有内存地址都是8(32位)或16(64位)的倍数(请参阅http://www.delorie.com/gnu/docs/glibc/libc_31.html )。 当然,这是系统特定的,其他实现可能有不同的规则。

因此,在您的示例中,假设它与glibc一起使用,即使A的实例大小为10,地址仍将是816的倍数