Search code examples
cgo

CGO: when should C.free() be used?


func Encode(p SomeStruct) (buf []byte, err error) {
    var bs bytes.Buffer
    if err = json.NewEncoder(&bs).Encode(p); err != nil {
        return
    }
    in := C.CString(bs.String())
    defer C.free(unsafe.Pointer(in))  //Is this necessary?
    res := make([]byte, 1024)
    out := C.CString(string(res))
    defer C.free(unsafe.Pointer(out)) //and this one 
    res := C.encode(in, out, 1024)  //int encode(char *, void *, int)
    //... ...
}

Question: shall I use C.free() to ensure that the code does not leak memory? I feel that this is not required as the variable is allocated by Go, not C, right?

My question is, will CString always allocate memory or, it will do that only if necessary?

// Go string to C string
// The C string is allocated in the C heap using malloc.
// It is the caller'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

Solution

  • As stated in the documentation, you need release the memory manually. The CString function (_Cfunc_CString in cmd/cgo/out.go) actually calls malloc from C standard library and the programmer is supposed to manage this memory. The returned string can be deallocated with C.free in the Go side or with free inside the C code.