首頁 >後端開發 >Golang >Go:回傳 CString 時如何處理記憶體洩漏?

Go:回傳 CString 時如何處理記憶體洩漏?

王林
王林轉載
2024-02-13 10:00:101019瀏覽

Go:返回 CString 时如何处理内存泄漏?

php小編西瓜在這裡為大家分享關於Go語言中處理返回CString時的記憶體洩漏問題的解決方法。在Go語言中,C字串是以null結尾的位元組數組,而Go語言的字串是以長度為前綴的位元組數組。當我們需要將Go字串轉換為C字串並返回時,需要注意記憶體的分配和釋放,以避免記憶體洩漏問題的發生。本文將介紹幾種處理記憶體洩漏的方法,幫助大家解決這個常見的問題。

問題內容

我有以下函數簽名,然後傳回 json 字串

func getdata(symbol, day, month, year *c.char) *c.char {
  combine, _ := json.marshal(combinerecords)
  log.println(string(combine))
  return c.cstring(string(combine))
}

然後在 python 中呼叫 go 程式碼

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)

它在 python 端工作得很好,但我擔心當在 python 端循環調用該函數時會出現記憶體洩漏。

如何處理記憶體洩漏?我應該返回 bytes 而不是 cstring 並在 python 端處理位元組以避免記憶體洩漏嗎?我確實找到了這個連結來處理它,但不知何故我不知道編組後返回的 json 字串的大小

解決方法

python 應該如下所示:

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 應該是這樣的:

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() {}

並使用此命令列產生共享庫:

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'
...

以上是Go:回傳 CString 時如何處理記憶體洩漏?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:stackoverflow.com。如有侵權,請聯絡admin@php.cn刪除