由于垃圾回收,指针是否会改变Go中的值?

时间:2017-02-27 00:04:10

标签: go cgo

我是一个相对新手。我一直在使用cgo和构建C api的接口。 C api使用已注册的回调函数和void* cookie参数进行回调。

以下是一些例证我的问题的代码:

/*
void cb(void *cookie) {
   callGo(cookie);
}

go_register_cb(void *ptr) {
   register_cb(&cb, ptr);
}
*/
import "C"

import "C"

//export callGo
callGo(ptr unsafe.Pointer) {
    x := (*MyStruct)(ptr)
    x.doSomething()
}

func (x *MyStruct) Start() {
    C.go_register_cb(unsafe.Pointer(x))
}

此代码导致G​​o指向Go指针的运行时错误。

我想我理解将Go指针保持在C-land中的基本含义,即在go垃圾收集器中不会考虑C-land引用,因此C可能最终使用过时的引用。

我无法将Go指针传递给本身包含Go指针的数据结构的特定要求更令人费解。对我来说唯一有意义的是,由于垃圾收集,Go中的指针可能会改变值(即,它们指向的地址)。是这种情况吗?

1 个答案:

答案 0 :(得分:2)

在运行时动态检查用于在Go代码和C代码之间传递指针的这些规则。所以当你打破它们时会发生错误。

你的猜测是正确的。由于垃圾收集,允许更改地址(指针已更新)。

注意here from golang.org

  

即使uintptr保存某个对象的地址,也就是垃圾   如果对象移动,收集器将不会更新该uintptr的值,   uintptr也不会阻止对象被回收。

因此可能会因gc而移动物体。