Dereferenziare un Puntatore con un vettore
La dereferenziazione di un Puntatore utilizzando un vettore (array) è procedura abbastanza complessa.
Si tratta in sostanza di assegnare direttamente ad una variabile vettoriale l'indirizzo di memoria del Puntatore da "dereferenziare" [Nota 1] [Nota 2], in modo tale che il vettore punti all'area di memoria riservata puntata dal suo Puntatore.
Per comprendere meglio la procedura che si adotterà, è necessario tenere presente che nel momento in cui una variabile vettoriale viene dichiarata e creata come nuovo oggetto, o comunque istanziata, essa occuperà una certa quantità di memoria attraverso l'apposita Sruttura, scritta in C e chiamata CARRAY, prevista dai sorgenti di Gambas. La mostriamo di seguito come dichiarta nel file header gbx_c_array.h:
typedef
struct {
OBJECT object;
int size;
int count;
TYPE type;
void *data;
int *dim;
void *ref;
}
CARRAY;
Dei membri appartenenti a tale Struttura possiamo distinguere:
int size = è un intero che dice la quantità di memoria occupata in byte dal tipo di dato dell'array dichiarato; int count = è un intero che indica quanti di elementi è composto l'array; TYPE type = è un intero lungo che definisce il tipo di dato così come descito nel file header gb_type_comon.h; void *data = è un Puntatore all'area di memoria riservata ove sono salvati i dati contenuti dall'array.
Pertanto, dovremo cambiare il valore che si riferisce all'indirizzo di memoria, rappresentato dal membro void *data, scrivendoci invece quello contenuto dal Puntatore esterno da dereferenziare.
Procederemo essenzialmente come segue:
Private LAT As Byte = 4
Public Sub Main()
Dim p, pv, ind As Pointer
Dim st As Stream
Dim b As Byte
Dim bb As Byte[]
' E' comunque necessario dichiarare e creare il vettore, definendo tipo e quanità degli elementi.
' In caso contrario bisognerà definire tipo e quantità successivamente con i "Memory Stream" all'interno dei rispettivi membri della Struttura "CARRAY":
bb = New Byte[LAT]
' A titolo esemplificativo scriviamo nell'area riservata puntata dal "Puntatore" quattro valori compatibili con il tipo Byte:
p = Alloc(LAT)
st = Memory p For Write
For b = 11 To 14
Write #st, b As Byte
Next
st.Close
' Otteniamo l'indirizzo di memoria del vettore (in tal modo penetriamo nella Struttura CARRAY, sopra descritta:
pv = Object.Address(bb)
' Poiché il valore del'indirizzo di memoria dei dati dell'array è contenuto a cominciare dal 3° byte (indice 32)
' dell'area di memoria riservata della Struttura "CARRAY", ci spostiamo all'interno di quell'area di memoria appunto al byte di indice 32:
ind = pv + 32
' Con i "Memory Stream" scriviamo a cominciare dal byte di indice 32 l'indirizzo di memoria contenuto dal "Puntatore":
st = Memory ind For Write
Write #st, p As Pointer
st.Close
' Verifichiamo il risultato.
' Il vettore non punta più alla sua area di memoria riservata "originaria", bensì ormai a quella puntata dal "Puntatore" da dereferenziare !
Print bb[0], bb[1], bb[2], bb[3]
Free(p)
End
Note
[1] Ricordiamo che "Dereferenziare" significa accedere al valore della variabile puntata dal Puntatore.
[2] In ordine all'operazione di "dereferenziazione" di una variabile di tipo Puntatore mediante le apposite funzioni native di Gambas e mediante i Memory Stream si rinvia alla seguente pagina della Wiki: http://www.gambas-it.org/wiki/index.php?title=Dereferenziare_un_Puntatore_di_Puntatore_con_le_funzioni_specifiche_di_dereferenziazione_e_con_i_Memory_Stream