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 的倍数=].
我试过这段代码:
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 的倍数=].