I'm trying to understand how to correctly free memory when using CString with cgo
in golang
This is the working code that I want to make "memory-safe":
basic.go
:
package main
// #include <stdlib.h>
import "C"
import (
"github.com/pemistahl/lingua-go"
)
var lan lingua.Language
//export Langdetectfunct
func Langdetectfunct(text *C.char) int {
textS := C.GoString(text);
detector := lingua.NewLanguageDetectorBuilder().
FromAllLanguages().
Build()
language, _ := detector.DetectLanguageOf(textS)
return int(language)
}
func main() {}
basic1.cpp
:
#include "basic.h"
int main() {
auto text = "It is a beautiful day, today";
int res = Langdetectfunct(const_cast<char *>(text));
std::cout << "res: " << res << std::endl;
}
After building basic.go with c-shared
buildmode:
raphy@raohy:~/go-lang-detect$ go build -o basic.so -buildmode=c-shared basic.go
and compiling basic1.cpp with basic.so
:
raphy@raohy:~/go-lang-detect$ g++ -o basic basic1.cpp ./basic.so
I get the correct output:
raphy@raohy:~/go-lang-detect$ ./basic
res: 17
And that's fine...
But: how to make the code "memory-safe"?
I tried in this way:
basic.go
:
package main
// #include <stdlib.h>
import "C"
import "unsafe"
import (
"github.com/pemistahl/lingua-go"
)
var lan lingua.Language
//export Langdetectfunct
func Langdetectfunct(text *C.char) int {
textS := C.GoString(text);
detector := lingua.NewLanguageDetectorBuilder().
FromAllLanguages().
Build()
language, _ := detector.DetectLanguageOf(textS)
return int(language)
C.free(unsafe.Pointer(text))
}
func main() {}
But, when, building, I get, understandably, this error:
raphy@raohy:~/go-lang-detect$ go build -o basic.so -buildmode=c-shared basic.go
./basic.go:39:1: missing return
If I put C.free(unsafe.Pointer(text))
before the return statement:
package main
// #include <stdlib.h>
import "C"
import "unsafe"
import (
"github.com/pemistahl/lingua-go"
)
var lan lingua.Language
//export Langdetectfunct
func Langdetectfunct(text *C.char) int {
textS := C.GoString(text);
detector := lingua.NewLanguageDetectorBuilder().
FromAllLanguages().
Build()
language, _ := detector.DetectLanguageOf(textS)
C.free(unsafe.Pointer(text))
return int(language)
}
func main() {}
I get : free(): invalid pointer
error, when running the executable:
raphy@raohy:~/go-lang-detect$ go build -o basic.so -buildmode=c-shared basic.go
raphy@raohy:~/go-lang-detect$ g++ -o basic basic1.cpp ./basic.so
raphy@raohy:~/go-lang-detect$ ./basic
free(): invalid pointer
Aborted (core dumped)
auto text = "It is a beautiful day, today";
text
is in the Stack place. You can't free it.