Heim  >  Artikel  >  Backend-Entwicklung  >  Go: Wie gehe ich mit Speicherlecks bei der Rückgabe eines CStrings um?

Go: Wie gehe ich mit Speicherlecks bei der Rückgabe eines CStrings um?

王林
王林nach vorne
2024-02-13 10:00:10924Durchsuche

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

php-Editor Xigua ist hier, um Ihnen die Lösung für das Speicherverlustproblem bei der Rückgabe von CString in der Go-Sprache mitzuteilen. In Go sind C-Strings nullterminierte Byte-Arrays, während Go-Strings Byte-Arrays mit vorangestellter Länge sind. Wenn wir einen Go-String in einen C-String und zurück konvertieren müssen, müssen wir auf die Zuweisung und Freigabe von Speicher achten, um Speicherlecks zu vermeiden. In diesem Artikel werden verschiedene Methoden zum Umgang mit Speicherlecks vorgestellt, um Ihnen bei der Lösung dieses häufigen Problems zu helfen.

Frageninhalt

Ich habe die folgende Funktionssignatur, die dann einen JSON-String zurückgibt

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

Dann rufen Sie den Go-Code in Python auf

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)

Auf der Python-Seite funktioniert es gut, aber ich mache mir Sorgen über einen Speicherverlust, wenn die Funktion in einer Schleife auf der Python-Seite aufgerufen wird.

Wie gehe ich mit Speicherlecks um? Soll ich zurückkehren bytes 而不是 cstring und die Bytes auf der Python-Seite verarbeiten, um Speicherlecks zu vermeiden? Ich habe diesen Link gefunden, um das Problem zu lösen, aber irgendwie weiß ich nicht, wie groß der zurückgegebene JSON-String nach dem Marshalling ist.

Workaround

Python sollte so aussehen:

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 sollte so aussehen:

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

Und generieren Sie die gemeinsam genutzte Bibliothek mit dieser Befehlszeile:

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

Das obige ist der detaillierte Inhalt vonGo: Wie gehe ich mit Speicherlecks bei der Rückgabe eines CStrings um?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:stackoverflow.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen