Freeing C variables in Golang?

huangapple go评论117阅读模式
英文:

Freeing C variables in Golang?

问题

我对在使用Go中的C变量时需要释放哪些变量感到困惑。

例如,如果我这样做:

  1. s := C.CString(`something`)

那么这块内存是否一直分配到我调用C.free(unsafe.Pointer(s))为止,还是在函数结束时由Go进行垃圾回收就可以了?

或者只有从导入的C代码创建的变量需要被释放,而从Go代码创建的这些C变量将由垃圾回收机制处理?

英文:

I'm confused about which variables need to be freed if I'm using C variables in Go.

For example, if I do this:

  1. s := C.CString(`something`)

Is that memory now allocated until I call C.free(unsafe.Pointer(s)), or is that OK to be garbage collected by Go when the function ends?

Or is it only variables that are created from the imported C code that need to be freed, and these C variables created from the Go code will be garbage collected?

答案1

得分: 7

文档中提到

  1. // Go字符串转为C字符串
  2. // C字符串在C堆中使用malloc分配
  3. // 调用者有责任安排释放它,比如通过调用C.free(如果需要,请确保包含stdlib.h)。
  4. func C.CString(string) *C.char

维基百科展示了一个示例

  1. package cgoexample
  2. /*
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. void myprint(char* s) {
  6. printf("%s", s);
  7. }
  8. */
  9. import "C"
  10. import "unsafe"
  11. func Example() {
  12. cs := C.CString("Hello from stdio\n")
  13. C.myprint(cs)
  14. C.free(unsafe.Pointer(cs))
  15. }

文章"C? Go? Cgo!"显示你不需要释放C数值类型:

  1. func Random() int {
  2. var r C.long = C.random()
  3. return int(r)
  4. }

但对于字符串,你需要释放:

  1. import "C"
  2. import "unsafe"
  3. func Print(s string) {
  4. cs := C.CString(s)
  5. C.fputs(cs, (*C.FILE)(C.stdout))
  6. C.free(unsafe.Pointer(cs))
  7. }
英文:

The documentation does mention:

  1. // Go string to C string
  2. // The C string is allocated in the C heap using malloc.
  3. // It is the caller&#39;s responsibility to arrange for it to be
  4. // freed, such as by calling C.free (be sure to include stdlib.h
  5. // if C.free is needed).
  6. func C.CString(string) *C.char

The wiki shows an example:

  1. package cgoexample
  2. /*
  3. #include &lt;stdio.h&gt;
  4. #include &lt;stdlib.h&gt;
  5. void myprint(char* s) {
  6. printf(&quot;%s&quot;, s);
  7. }
  8. */
  9. import &quot;C&quot;
  10. import &quot;unsafe&quot;
  11. func Example() {
  12. cs := C.CString(&quot;Hello from stdio\n&quot;)
  13. C.myprint(cs)
  14. C.free(unsafe.Pointer(cs))
  15. }

The article "C? Go? Cgo!" shows that you don't need to free C numeric types:

  1. func Random() int {
  2. var r C.long = C.random()
  3. return int(r)
  4. }

But you would for string:

  1. import &quot;C&quot;
  2. import &quot;unsafe&quot;
  3. func Print(s string) {
  4. cs := C.CString(s)
  5. C.fputs(cs, (*C.FILE)(C.stdout))
  6. C.free(unsafe.Pointer(cs))
  7. }

huangapple
  • 本文由 发表于 2014年10月4日 14:45:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/26190410.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定