Maison  >  Article  >  développement back-end  >  Go : Comment gérer les fuites de mémoire lors du retour d'une CString ?

Go : Comment gérer les fuites de mémoire lors du retour d'une CString ?

王林
王林avant
2024-02-13 10:00:10926parcourir

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

l'éditeur php Xigua est là pour partager avec vous la solution au problème de fuite de mémoire lors du retour de CString en langage Go. Dans Go, les chaînes C sont des tableaux d'octets terminés par un caractère nul, tandis que les chaînes Go sont des tableaux d'octets avec préfixe de longueur. Lorsque nous devons convertir une chaîne Go en chaîne C et inversement, nous devons faire attention à l'allocation et à la libération de mémoire pour éviter les fuites de mémoire. Cet article présentera plusieurs méthodes pour gérer les fuites de mémoire afin de vous aider à résoudre ce problème courant.

Contenu de la question

J'ai la signature de fonction suivante qui renvoie ensuite une chaîne json

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

Ensuite, appelez le code go en 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)

Cela fonctionne bien côté python, mais je m'inquiète d'une fuite de mémoire lors de l'appel de la fonction en boucle côté python.

Comment gérer les fuites de mémoire ? Dois-je revenir bytes 而不是 cstring et traiter les octets côté python pour éviter les fuites de mémoire ? J'ai trouvé ce lien pour le gérer mais d'une manière ou d'une autre, je ne connais pas la taille de la chaîne json renvoyée après le marshalling

Solution de contournement

python devrait ressembler à ceci :

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 devrait ressembler à ceci :

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

Et générez la bibliothèque partagée en utilisant cette ligne de commande :

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

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer