Освобождение переменных C в Golang?

Я не понимаю, какие переменные нужно освобождать, если я использую переменные C в Go.

Например, если я сделаю это:

    s := C.CString(`something`)

Эта память теперь выделена до тех пор, пока я не вызову C.free(unsafe.Pointer(s)), или это нормально, чтобы Go собирал мусор, когда функция завершается?

Или нужно освободить только переменные, созданные из импортированного кода C, и эти переменные C, созданные из кода Go, будут удалены сборщиком мусора?


go c cgo
person Alasdair    schedule 04.10.2014    source источник


Ответы (1)


В документации упоминается:

// 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

вики показывает пример:

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))
}
person VonC    schedule 04.10.2014
comment
Применяется ли то же самое ко всем переменным, преобразованным в переменные C? Нравится v := C.l_int32(123)? - person Alasdair; 04.10.2014
comment
@Alasdair Я не знал о C.l_xxx, только C.xxx, но для числового типа вам не нужно освобождать память. Я отредактировал ответ со ссылкой на статью, содержащую примеры. - person VonC; 04.10.2014
comment
l_xxx по какой-то причине используется библиотекой Leptonica. Я не уверен, в чем разница, но Go с радостью создает эти типы, а Leptonica с радостью их принимает. - person Alasdair; 04.10.2014
comment
@Alasdair l_xxx - это просто определения типов для обычных типов чисел, например, если бы вы сделали type LUint64 uint64 в Go. - person OneOfOne; 04.10.2014