为了账号安全,请及时绑定邮箱和手机立即绑定

Go 保证地址不变吗?

Go 保证地址不变吗?

Go
繁花如伊 2021-07-30 09:04:28
给定一个对象obj是否有保证uintptr(unsafe.Pointer(&obj))无论何时调用它都会始终评估为相同的值?当然,Go 保证如果您将两个指针指向同一个对象,它们将始终比较相等。尽管实现可能会在内存中移动对象并透明地更新指向它的所有指针。如果您考虑像Mark-and-Compact这样的垃圾收集策略,这会很有趣。是否允许实现者使用这样的垃圾收集策略?
查看完整描述

3 回答

?
杨魅力

TA贡献1811条经验 获得超6个赞

没有这样的保证,完全可以实现移动收集器。


事实上,虽然垃圾收集器今天不移动堆对象,但在 Go 1.3 中堆栈可以在需要增长时移动,因此完全有可能


var obj int

fmt.Println(uintptr(unsafe.Pointer(&obj)))

bigFunc()

fmt.Println(uintptr(unsafe.Pointer(&obj)))

将打印两个不同的指针,因为 bigFunc 增加了堆栈,导致 obj 和堆栈上的所有其他内容移动。




查看完整回答
反对 回复 2021-08-02
?
汪汪一只猫

TA贡献1898条经验 获得超8个赞

规范中没有任何内容可以保证这一点,可能是为了允许该语言的实现在未来使用压缩垃圾收集器。在这个 golang-nuts 线程中,一位开发人员建议如果unsafe.Pointer值固定在内存中,则可以进行压缩 GC ,但这不能扩展到所有unitptr值。

对于当前的 Go 运行时,我相信这是真的,但依赖它仍然是未定义的行为。但有一些警告:

  1. 如果obj是零大小类型,则表达式的值可能不是唯一的,如规范中所述。

  2. 在程序的整个生命周期中,一个特定的uintptr值可能会引用不同的对象。


查看完整回答
反对 回复 2021-08-02
?
繁星淼淼

TA贡献1775条经验 获得超11个赞

没有绝对的保证。特别是如果 Go 为其标记和清除垃圾收集器添加了压缩。

如果需要,任何垃圾收集器都会更新存储在指针类型和类型中的地址unsafe.Pointeruintptr垃圾收集器不会更新以类型存储为无符号整数的地址。该uintptr类型不是指针类型,而是整数类型。

数字类型

uintptr 一个足以存储指针值的未解释位的无符号整数

将 unsafe.Pointers 转换为 uintptr

指针应该一直保存在 unsafe.Pointers - 而不是 uintptrs - 中。

拉斯

对于你的例子,

uintptr(unsafe.Pointer(&obj))

你有一个无符号整数,而不是地址。


查看完整回答
反对 回复 2021-08-02
  • 3 回答
  • 0 关注
  • 324 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信