Differenze tra le versioni di "Dereferenziare un Puntatore con un vettore"

Da Gambas-it.org - Wikipedia.
 
(11 versioni intermedie di uno stesso utente non sono mostrate)
Riga 1: Riga 1:
 
La dereferenziazione di un ''Puntatore'' utilizzando un vettore (''array'') è procedura abbastanza complessa.
 
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, in modo tale che il vettore punti all'area di memoria riservata puntata dal suo ''Puntatore''.
+
Si tratta in sostanza di assegnare <SPAN Style="text-decoration:underline">direttamente</span> ad una variabile vettoriale l'indirizzo di memoria del ''Puntatore'' da "''dereferenziare'' " <SUP>&#91;[[#Note|Nota 1]]&#93;</sup> <SUP>&#91;[[#Note|Nota 2]]&#93;</sup>, 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'':
+
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 ''Struttura'', 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
 
  typedef
Riga 24: Riga 24:
  
 
Procederemo essenzialmente come segue:
 
Procederemo essenzialmente come segue:
  Private LAT As Byte = 4
+
  Private Const LAT As Byte = 4
 
   
 
   
 
   
 
   
Riga 36: Riga 36:
 
  <FONT Color=gray>' ''E' comunque necessario dichiarare e creare il vettore, definendo tipo e quanità degli elementi.''
 
  <FONT Color=gray>' ''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":''</font>
 
  ' ''In caso contrario bisognerà definire tipo e quantità successivamente con i "Memory Stream" all'interno dei rispettivi membri della Struttura "CARRAY":''</font>
  bb = New Byte[LAT]
+
  bb = New Byte[LAT]
 
    
 
    
  <FONT Color=gray>' ''A titolo esemplificativo scriviamo nell'area riservata puntata dal "Puntatore" quattro valori compatibili con il tipo Byte:''</font>
+
  <FONT Color=gray>' ''A titolo esemplificativo scriviamo nell'area riservata puntata dal "Puntatore" quattro valori compatibili con il tipo Byte.''
  p = Alloc(LAT)
+
' ''La variabile "p" è il Puntatore che dovrà essere successivamente dereferenziato attraverso un vettore.</font>
  st = Memory p For Write
+
  p = Alloc(SizeOf(gb.Byte), LAT)
  For b = 11 To 14
+
  st = Memory p For Write
    Write #st, b As Byte
+
  For b = 11 To 14
  Next
+
    Write #st, b As Byte
  st.Close
+
  Next
   
+
  st.Close
 
+
   
  <FONT Color=gray>' ''Otteniamo l'indirizzo di memoria del vettore (in tal modo penetriamo nella Struttura CARRAY, sopra descritta:''</font>
+
  <FONT Color=gray>' ''Otteniamo l'indirizzo di memoria del vettore - come Oggetto  <SUP>&#91;[[#Note|Nota 3]]&#93;</sup> - mediante il Metodo "Object.Address()"  (in tal modo penetriamo nella Struttura CARRAY, sopra descritta):''</font>
  pv = Object.Address(bb)
+
  pv = Object.Address(bb)
  <FONT Color=gray>' ''Poiché il valore del'indirizzo di memoria dei dati dell'array è contenuto a cominciare dal 3° byte (indice 32)''
+
  <FONT Color=gray>' ''Poiché il valore dell'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:''</font>
' ''dell'area di memoria riservata della Struttura "CARRAY", ci spostiamo all'interno di quell'area di memoria appunto al byte di indice 32:''</font>
+
  ind = pv + 32
  ind = pv + 32
 
 
  <FONT Color=gray>' ''Con i "Memory Stream" scriviamo a cominciare dal byte di indice 32 l'indirizzo di memoria contenuto dal "Puntatore":''</font>
 
  <FONT Color=gray>' ''Con i "Memory Stream" scriviamo a cominciare dal byte di indice 32 l'indirizzo di memoria contenuto dal "Puntatore":''</font>
  st = Memory pv For Write
+
  st = Memory ind For Write
  Write #st, p As Pointer
+
  Write #st, p As Pointer
  st.Close
+
  st.Close
 
    
 
    
  <FONT Color=gray>' ''Verifichiamo il risultato:''</font>
+
  <FONT Color=gray>' ''Verifichiamo il risultato.''
  Print bb[0], bb[1], bb[2], bb[3]
+
' ''Il vettore non punta più alla sua area di memoria riservata "originaria", bensì ormai a quella puntata dal "Puntatore" da dereferenziare !</font>
 +
  Print bb[0], bb[1], bb[2], bb[3]
 
    
 
    
  Free(p)
+
<FONT Color=gray>' ''Libera la memoria precedentemente allocata e si assicura che il "Puntatore" non punti a un indirizzo di memoria rilevante:''</font>
 +
  Free(p)
 +
  p = 0
 
    
 
    
 
  '''End'''
 
  '''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: [[Dereferenziare_un_Puntatore_di_Puntatore_con_le_funzioni_specifiche_di_dereferenziazione_e_con_i_Memory_Stream|Dereferenziare un Puntatore di Puntatore con le funzioni specifiche di dereferenziazione e con i Memory Stream]]
 +
 +
[3] Con il Metodo "'''Object.Address(vettore)'''" si ottiene l'indirizzo di memoria dell'Oggetto vettore; mentre con la Proprietà "'''vettore.Data'''" si ottiene l'indirizzo della specifica area di memoria dell'Oggetto vettore ove sono memorizzati i valori contenuti negli elementi del vettore medesimo.

Versione attuale delle 20:08, 20 ago 2022

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 Struttura, 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 Const 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.
' La variabile "p" è il Puntatore che dovrà essere successivamente dereferenziato attraverso un vettore.
 p = Alloc(SizeOf(gb.Byte), 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 - come Oggetto  [Nota 3] - mediante il Metodo "Object.Address()"  (in tal modo penetriamo nella Struttura CARRAY, sopra descritta):
 pv = Object.Address(bb)
' Poiché il valore dell'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]
  
' Libera la memoria precedentemente allocata e si assicura che il "Puntatore" non punti a un indirizzo di memoria rilevante:
 Free(p)
 p = 0
  
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: Dereferenziare un Puntatore di Puntatore con le funzioni specifiche di dereferenziazione e con i Memory Stream

[3] Con il Metodo "Object.Address(vettore)" si ottiene l'indirizzo di memoria dell'Oggetto vettore; mentre con la Proprietà "vettore.Data" si ottiene l'indirizzo della specifica area di memoria dell'Oggetto vettore ove sono memorizzati i valori contenuti negli elementi del vettore medesimo.