Home > Article > Backend Development > Go: How to handle memory leaks when returning a CString?
php editor Xigua is here to share with you the solution to the memory leak problem when returning CString in the Go language. In Go, C strings are null-terminated byte arrays, while Go strings are length-prefixed byte arrays. When we need to convert a Go string to a C string and back, we need to pay attention to the allocation and release of memory to avoid memory leaks. This article will introduce several methods to deal with memory leaks to help you solve this common problem.
I have the following function signature, which then returns a json string
func getdata(symbol, day, month, year *c.char) *c.char { combine, _ := json.marshal(combinerecords) log.println(string(combine)) return c.cstring(string(combine)) }
Then call the go code in python
import ctypes from time import sleep library = ctypes.cdll.LoadLibrary('./deribit.so') get_data = library.getData # Make python convert its values to C representation. # get_data.argtypes = [ctypes.c_char_p, ctypes.c_char_p,ctypes.c_char_p,ctypes.c_char_p] get_data.restype = ctypes.c_char_p for i in range(1,100): j= get_data("BTC".encode("utf-8"), "5".encode("utf-8"), "JAN".encode("utf-8"), "23".encode("utf-8")) # j= get_data(b"BTC", b"3", b"JAN", b"23") print('prnting in Python') # print(j) sleep(1)
It works fine on the python side, but I'm worried about a memory leak when calling the function in a loop on the python side.
How to deal with memory leaks? Should I return bytes
instead of cstring
and handle the bytes on the python side to avoid memory leaks? I did find this link to handle it but somehow I don't know the size of the json string returned after marshalling
python should look like this:
import ctypes from time import sleep library = ctypes.cdll('./stackoverflow.so') get_data = library.getdata free_me = library.freeme free_me.argtypes = [ctypes.pointer(ctypes.c_char)] get_data.restype = ctypes.pointer(ctypes.c_char) for i in range(1,100): j = get_data("", "", "") print(ctypes.c_char_p.from_buffer(j).value) free_me(j) sleep(1)
go should look like this:
package main /* #include <stdlib.h> */ import "c" import ( "log" "unsafe" ) //export getdata func getdata(symbol, day, month, year *c.char) *c.char { combine := "combine" log.println(string(combine)) return c.cstring(string(combine)) } //export freeme func freeme(data *c.char) { c.free(unsafe.pointer(data)) } func main() {}
And use this command line to generate the shared library:
python3 --version python 3.8.10 go version go version go1.19.2 linux/amd64 go build -o stackoverflow.so -buildmode=c-shared github.com/sjeandeaux/stackoverflow python3 stackoverflow.py 2023/01/03 13:54:14 combine b'combine' ...
from ubuntu:18.04 run apt-get update -y && apt-get install python -y copy stackoverflow.so stackoverflow.so copy stackoverflow.py stackoverflow.py cmd ["python", "stackoverflow.py"]
docker build --tag stackoverflow . docker run -ti stackoverflow 2023/01/03 15:04:24 combine b'combine' ...
The above is the detailed content of Go: How to handle memory leaks when returning a CString?. For more information, please follow other related articles on the PHP Chinese website!