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

Da Gambas-it.org - Wikipedia.
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 <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''.
+
Si tratta in sostanza di assegnare <U>direttamente</u> 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 ''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'':
+
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 dichiarata nel file header ''gbx_c_array.h'':
  
 
  typedef
 
  typedef
Riga 19: Riga 19:
 
  ''int size'' = è un intero che dice la quantità di memoria occupata in byte dal tipo di dato dell'array dichiarato;
 
  ''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;
 
  ''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'';
+
  ''TYPE type'' = è un intero lungo che definisce il tipo di dato così come descritto nel file header ''gb_type_comon.h'';
 
  ''void *data'' = è un ''Puntatore'' all'area di memoria riservata ove sono salvati i dati contenuti dall'array.
 
  ''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.
 
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:
+
Procederemo come segue:
Private Const LAT As Byte = 4
 
 
 
 
  Public Sub Main()
 
  Public Sub Main()
 
    
 
    
   Dim p, pv, ind As Pointer
+
   Dim <FONT Color=red>p</font>, <FONT Color=green>pv</font>, <FONT Color=darkorange>ind</font> As Pointer
 
   Dim st As Stream
 
   Dim st As Stream
 
   Dim b As Byte
 
   Dim b As Byte
Riga 36: Riga 33:
 
  <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[4]
 
    
 
    
 
  <FONT Color=gray>' ''A titolo esemplificativo scriviamo nell'area riservata puntata dal "Puntatore" quattro valori compatibili con il tipo Byte.''
 
  <FONT Color=gray>' ''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.</font>
+
  ' ''La variabile "p" è il Puntatore che dovrà essere successivamente dereferenziato attraverso un vettore.''</font>
   p = Alloc(SizeOf(gb.Byte), LAT)
+
   <FONT Color=red>p</font> = Alloc(SizeOf(gb.Byte), bb.Count)
   st = Memory p For Write
+
   st = Memory <FONT Color=red>p</font> For Write
 
   For b = 11 To 14
 
   For b = 11 To 14
 
     Write #st, b As Byte
 
     Write #st, b As Byte
Riga 48: Riga 45:
 
      
 
      
 
  <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>
 
  <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)
+
   <FONT Color=green>pv</font> = Object.Address(bb)
 
  <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>
 
  <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>
   ind = pv + 32
+
   <FONT Color=darkorange>ind</font> = <FONT Color=green>pv</font> + 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 ind For Write
+
   st = Memory <FONT Color=darkorange>ind</font> For Write
   Write #st, p As Pointer
+
   Write #st, <FONT Color=red>p</font> As Pointer
 
   st.Close
 
   st.Close
 
    
 
    
Riga 61: Riga 58:
 
    
 
    
 
  <FONT Color=gray>' ''Libera la memoria precedentemente allocata e si assicura che il "Puntatore" non punti a un indirizzo rilevante di memoria:''</font>
 
  <FONT Color=gray>' ''Libera la memoria precedentemente allocata e si assicura che il "Puntatore" non punti a un indirizzo rilevante di memoria:''</font>
   Free(p)
+
   Free(<FONT Color=red>p</font>)
   p = 0
+
   <FONT Color=red>p</font> = 0
 
    
 
    
 
  End
 
  End
Riga 71: Riga 68:
 
[1] Ricordiamo che "''Dereferenziare''" significa accedere al valore della variabile puntata dal ''Puntatore''.
 
[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]]
+
[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.
 
[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 delle 04:12, 9 nov 2024

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 dichiarata 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 descritto 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 come segue:

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[4]
 
' 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), bb.Count)
 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 rilevante di memoria:
 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.