Deallocare successivamente un'area di memoria allocata in una funzione esterna di una libreria da noi scritta

Da Gambas-it.org - Wikipedia.

Una funzione esterna, contenuta in una libreria da noi scritta, potrebbe fra l'altro prevedere l'allocazione di un area di memoria, puntata da una variabile di tipo Puntatore che al termine deve essere restituito alla funzione chiamante nel progetto Gambas.

Tale allocazione non potrebbe in tal modo essere annullata, generando così il fenomeno del "memory leak".

Per ovviare a tale problema, si possono adottare almeno due modalità.

Uso della funzione esterna "free( )"

La prima modalità prevede l'uso della funzione esterna "free()" con le accortezze descritte in questa pagina della Wiki:
Uso del nome di una funzione già utilizzato da Gambas.

Mostriamo un esempio pratico:

Library "/tmp/libmia"

' char * funz(void)
' Copia una stringa nell'area puntata dal Puntatore.
Private Extern funz() As String


Library "libc:6"

' void free (void *__ptr)
' Free a block allocated by `malloc', `realloc' or `calloc'.
Private Extern free_C(__ptr As Pointer) Exec "free"


Public Sub Main()
 
 Dim t As String
 
 CreaSo()
   
 t = funz()
   
 Print t
  
 free_C(t)
  
End

Private Procedure CreaSo()
 
 File.Save("/tmp/libmia.c", "#include <stdlib.h>\n#include <string.h>\n\n" &
           "char * funz(void) {\n\n" &
           "   char *s = calloc(16, sizeof(char));\n\n" &
           "   strcpy(s, \"testo qualsiasi\");\n\n"
           "   return s;\n\n}")
           
 Shell "gcc -o /tmp/libmia.so /tmp/libmia.c -shared -fPIC" Wait
 
End


Uso di apposita funzione esterna da noi scritta

Un'altra modalità prevede che nella medesima libreria dinamica condivisa, contenente la funzione esterna che ha allocato l'area di memoria, abbia anche una funzione esterna che provveda a deallocare quella porzione di memoria precedentemente riservata.

Mostriamo un semplice esempio:

Library "/tmp/libmia"

' char * funz(void)
' Copia una stringa nel'area puntata dal Puntatore.
Private Extern funz() As String

' void libera_memoria(void * buffer)
' Libera la memoria precedentemente allocata nella libreria esterna.
Private Extern libera_memoria(buffer As Pointer)
 

Public Sub Main()
 
 Dim t As String
 
 CreaSo()
   
 t = funz()
   
 Print t
  
 libera_memoria(t)
  
End


Private Procedure CreaSo()
 
 File.Save("/tmp/libmia.c", "#include <stdlib.h>\n#include <string.h>\n\n" &
           "char * funz(void) {\n\n" &
           "   char *s = calloc(16, sizeof(char));\n\n" &
           "   strcpy(s, \"Testo qualsiasi\");\n\n"
           "   return s;\n\n}" &
           "\n\n\n" &
           "void libera_memoria(void * buffer) {\n\n" &
           "   if (buffer) {\n\n" &
           "      free(buffer);\n" &
           "      buffer=NULL;\n      }\n\n}")
           
 Shell "gcc -o /tmp/libmia.so /tmp/libmia.c -shared -fPIC" Wait
 
End