Freeing C variables in Golang?

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

Freeing C variables in Golang?

问题

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

例如,如果我这样做:

    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:

    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

文档中提到

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

维基百科展示了一个示例

package cgoexample

/*
#include <stdio.h>
#include <stdlib.h>

void myprint(char* s) {
        printf("%s", s);
}
*/
import "C"

import "unsafe"

func Example() {
        cs := C.CString("Hello from stdio\n")
        C.myprint(cs)
        C.free(unsafe.Pointer(cs))
}

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

func Random() int {
    var r C.long = C.random()
    return int(r)
}

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

import "C"
import "unsafe"

func Print(s string) {
    cs := C.CString(s)
    C.fputs(cs, (*C.FILE)(C.stdout))
    C.free(unsafe.Pointer(cs))
}
英文:

The documentation does mention:

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

The wiki shows an example:

package cgoexample

/*
#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;

void myprint(char* s) {
        printf(&quot;%s&quot;, s);
}
*/
import &quot;C&quot;

import &quot;unsafe&quot;

func Example() {
        cs := C.CString(&quot;Hello from stdio\n&quot;)
        C.myprint(cs)
        C.free(unsafe.Pointer(cs))
}

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

func Random() int {
    var r C.long = C.random()
    return int(r)
}

But you would for string:

import &quot;C&quot;
import &quot;unsafe&quot;

func Print(s string) {
    cs := C.CString(s)
    C.fputs(cs, (*C.FILE)(C.stdout))
    C.free(unsafe.Pointer(cs))
}

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:

确定