如何/何时释放由 Go 代码创建的 C 字符串的内存?

jnb*_*bdz 3 go cgo

这是我的代码:

helloworld.go :

package main

/*
#include <stdlib.h>
*/
import "C"

import "unsafe"

//export HelloWorld
func HelloWorld() *C.char {
    cs := C.CString("Hello World!")
    C.free(unsafe.Pointer(cs))
    return cs
}

func main() {}
Run Code Online (Sandbox Code Playgroud)

节点helloworld.cc

#include "helloworld.h"
#include <node.h>
#include <string>

namespace demo {

using v8::FunctionCallbackInfo;
using v8::Isolate;
using v8::Local;
using v8::Object;
using v8::String;
using v8::Value;

void Method(const FunctionCallbackInfo<Value>& args) {
  Isolate* isolate = args.GetIsolate();
  args.GetReturnValue().Set(String::NewFromUtf8(isolate, HelloWorld()));
}

void init(Local<Object> exports) {
  NODE_SET_METHOD(exports, "hello", Method);
}

NODE_MODULE(helloworld, init)

}
Run Code Online (Sandbox Code Playgroud)

当我执行代码时,我得到:

?Oc

或者

??#

或者

???

等等

其实是随机的。我似乎每次都得到不同的东西。

可能是我从方法传递字符数组HelloWorld()

我错过了什么?

更新

当我删除:

C.free(unsafe.Pointer(cs))
Run Code Online (Sandbox Code Playgroud)

我得到了好的字符串。而不是随机字符。

但我需要C.free释放内存。这里推荐:https : //blog.golang.org/c-go-cgo

对 C.CString 的调用返回一个指向 char 数组开头的指针,因此在函数退出之前,我们将其转换为 unsafe.Pointer 并使用 C.free 释放内存分配。

我不确定如何做到这一点。

mko*_*iva 5

链接的示例释放了分配的内存,因为没有其他代码需要它。

如果您的 Go 函数需要返回一些分配的内存以便某些 C 代码可以使用它,那么 Go 函数不应调用 C.free,而是使用该内存的 C 代码应负责在不需要之后释放它它了。

任意示例:

cgo/测试/issue20910.go

cgo/测试/issue20910.c