go - 释放 C 对象的 Go 结构

标签 go cgo

当通过基于 C.malloc 的调用分配单个对象时,我们必须释放新项目,因为 Go 垃圾收集器不知道它们。

如:

s := C.CString(l)
defer C.free(unsafe.Pointer(s))

但是,当我们创建 C 对象的 slice 时,我们需要释放它们吗?

如:

b := make([]C.uchar, C.int(40))

我试图使用类似 defer C.free(unsafe.Pointer(&b[0])) 的东西,但是它会产生 free(): invalid pointer 和一个中止信号。

我看到三个可能的答案:

  1. Go 垃圾收集器知道通过 make 调用创建的对象,因此 b 将被 Go 运行时垃圾收集。
  2. Go 垃圾收集器知道通过 make 调用创建的 slice ,但不知道 slice 中包含的 C.uchar。因此我们需要遍历 slice ,并释放每个项目
  3. 我错误地调用了 slice b 的释放。

如果有的话,我的结论中哪些是正确的?否则实际发生了什么?

最佳答案

没那么复杂

cgo 生成一个 Go 类型 C.uchar,其内存布局完全匹配 C 类型 unsigned char

Go 表达式 make([]C.uchar, 40) 像往常一样分配一个 Go slice ,其底层数组为 Go 类型 C.uchar

Go 有一个垃圾收集器 (GC)。当不再有任何 Go 对 slice 及其底层数组的引用时,它就有资格进行 Go 垃圾回收。

Go GC 不知道也不关心任何 C 代码。


参见 Go: Command cgo .

关于go - 释放 C 对象的 Go 结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54972955/

相关文章:

sqlite - 是否可以通过 docker golang :alpine image? 构建静态 sqlite Go 应用程序

java - Intellij 上的 Golang 插件

go - 如何在 Go 中使用 Minio 预签名 URL

戈朗/mgo : leave out empty fields from insert

go - standard_init_linux.go :207: exec user process caused "no such file or directory" while trying to statically link c libs

go - 需要测试某个时间是否在同一天的其他两次之间

pointers - 如何在go中获取函数的地址?

utf-8 - 在 Go 中使用 C 库时,如何正确地将 UTF-8 编码的字符数组转换为 Go 字符串?

go - cgo:Go 内存中的 Go 指针

go - 将带有 uint8_t *num 的 C 结构转换为 Go