Dereferenziare un Puntatore con un vettore: differenze tra le versioni
Nessun oggetto della modifica |
Nessun oggetto della modifica |
||
| 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 < | Si tratta in sostanza di assegnare <U>direttamente</u> ad una variabile vettoriale l'indirizzo di memoria del ''Puntatore'' da "''dereferenziare'' " <SUP>[[[#Note|nota 1]]]</sup> <SUP>[[[#Note|nota 2]]]</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 | 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 | ''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 | Procederemo come segue: | ||
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[ | 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), | <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>[[[#Note|Nota 3]]]</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>[[[#Note|Nota 3]]]</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: [[ | [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 05: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.