Differenze tra le versioni di "Dereferenziare un Puntatore con un vettore"
(21 versioni intermedie di uno stesso utente non sono mostrate) | |||
Riga 1: | Riga 1: | ||
− | + | 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''. | |
− | + | Possiamo dereferenziare un ''Puntatore'', usando <U>direttamente</u> un Vettore, mediante almeno due modalità. | |
− | 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 | + | ==Uso della Proprietà ".Data" del Vettore== |
+ | Public Sub Main() | ||
+ | |||
+ | Dim bb As Byte[] | ||
+ | Dim <FONT Color=red>p</font> As Pointer | ||
+ | Dim st As Stream | ||
+ | Dim b As Byte | ||
+ | |||
+ | <FONT Color=gray>' ''Crea il vettore, definendo tipo e quantità degli elementi:''</font> | ||
+ | bb = New Byte[4] | ||
+ | |||
+ | <FONT Color=gray>' ''A titolo esemplificativo scrive 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> | ||
+ | <FONT Color=red>p</font> = Alloc(SizeOf(gb.Byte), bb.Count) | ||
+ | st = Memory <FONT Color=red>p</font> For Write | ||
+ | For b = 11 To 14 | ||
+ | Write #st, b As Byte | ||
+ | Next | ||
+ | st.Close | ||
+ | |||
+ | <FONT Color=gray>' ''Con i "Memory Stream" scrive nell'area di memoria, puntata dalla Proprietà ".Data" del vettore usato, i dati contenuti dal "Puntatore" da dereferenziare:''</font> | ||
+ | st = Memory bb.Data For Write | ||
+ | Write #st, <FONT Color=red>p</font>, bb.Count <FONT Color=gray>' ''Scrive una quantità definita di dati, contenuti dal "Puntatore"'' <SUP>[[[#Note|nota 3]]]</sup></font> | ||
+ | st.Close | ||
+ | |||
+ | <FONT Color=gray>' ''Verifica il risultato:''</font> | ||
+ | Print bb[0], bb[1], bb[2], bb[3] | ||
+ | |||
+ | <FONT Color=gray>' ''Libera la memoria precedentemente allocata e si assicura che il "Puntatore" non punti a un indirizzo rilevante di memoria:''</font> | ||
+ | Free(<FONT Color=red>p</font>) | ||
+ | <FONT Color=red>p</font> = 0 | ||
+ | |||
+ | End | ||
+ | |||
+ | |||
+ | ==Uso del membro "void *data" della Struttura costitutiva dell'Oggetto "Array" di Gambas== | ||
+ | La dereferenziazione di un ''Puntatore'' utilizzando il membro "void *data" della Struttura, costitutiva dell'Oggetto "Array" di Gambas, è procedura abbastanza complessa. <SUP>[[[#Note|nota 4]]]</sup> | ||
+ | <BR>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 essendo costitutiva dell'Oggetto "Array" del linguaggio Gambas. | ||
+ | <BR>La mostriamo di seguito come dichiarata nel file header ''gbx_c_array.h'': | ||
typedef | typedef | ||
Riga 11: | Riga 49: | ||
int count; | int count; | ||
TYPE type; | TYPE type; | ||
− | void *data; | + | <FONT Color=#B22222>void *data</font>; |
int *dim; | int *dim; | ||
void *ref; | void *ref; | ||
Riga 19: | Riga 57: | ||
''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() | |
− | |||
− | |||
− | |||
− | 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 | ||
Dim bb As Byte[] | Dim bb As Byte[] | ||
− | <FONT Color=gray>' ''E' comunque necessario dichiarare e creare il vettore, definendo tipo e | + | <FONT Color=gray>' ''E' comunque necessario dichiarare e creare il vettore, definendo tipo e quantità 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[4] | |
− | <FONT Color=gray>' ''A titolo esemplificativo | + | <FONT Color=gray>' ''A titolo esemplificativo scrive 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> | |
− | + | <FONT Color=red>p</font> = Alloc(SizeOf(gb.Byte), bb.Count) | |
− | + | st = Memory <FONT Color=red>p</font> For Write | |
− | + | For b = 11 To 14 | |
− | + | Write #st, b As Byte | |
− | + | Next | |
− | + | st.Close | |
+ | |||
+ | <FONT Color=gray>' ''Ottiene l'indirizzo di memoria del vettore - come Oggetto'' <SUP>[[[#Note|nota 5]]]</sup>'' ''- mediante il Metodo "Object.Address()" (in tal modo penetra nella Struttura CARRAY, sopra descritta):''</font> | ||
+ | <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", si sposta all'interno di quell'area di memoria appunto al byte di indice 32:''</font> | ||
+ | <FONT Color=darkorange>ind</font> = <FONT Color=green>pv</font> + 32 | ||
+ | <FONT Color=gray>' ''Con i "Memory Stream" scrive a cominciare dal byte di indice 32 l'indirizzo di memoria contenuto dal "Puntatore":''</font> | ||
+ | st = Memory <FONT Color=darkorange>ind</font> For Write | ||
+ | Write #st, <FONT Color=red>p</font> As Pointer | ||
+ | st.Close | ||
− | <FONT Color=gray>' '' | + | <FONT Color=gray>' ''Verifica il risultato.'' |
− | + | ' ''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] | |
− | ' '' | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | <FONT Color=gray>' '' | + | <FONT Color=gray>' ''Libera la memoria precedentemente allocata e si assicura che il "Puntatore" non punti a un indirizzo rilevante di memoria:''</font> |
− | + | Free(<FONT Color=red>p</font>) | |
+ | <FONT Color=red>p</font> = 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] Per questa scrittura dei dati in un flusso, contenuti nell'area di memoria puntata da un ''Puntatore'', vedasi la seguente pagina: [[Write#Scrivere_in_un_file_i_dati_contenuti_in_un.27area_di_memoria_puntata_da_un_Puntatore|Scrivere in un file i dati contenuti in un'area di memoria puntata da un Puntatore]] | ||
+ | |||
+ | [4] Al riguardo vedasi anche questo paragrafo: [[Assegnare_ad_un_vettore_i_valori_contenuti_da_un'area_di_memoria_puntata_da_un_Puntatore#Assegnando_il_Puntatore_al_membro_Data_della_Struttura_CARRAY_dei_sorgenti_di_Gambas|Assegnando il Puntatore al membro Data della Struttura CARRAY dei sorgenti di Gambas]] | ||
+ | |||
+ | [5] 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 17:40, 9 nov 2024
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.
Possiamo dereferenziare un Puntatore, usando direttamente un Vettore, mediante almeno due modalità.
Uso della Proprietà ".Data" del Vettore
Public Sub Main() Dim bb As Byte[] Dim p As Pointer Dim st As Stream Dim b As Byte ' Crea il vettore, definendo tipo e quantità degli elementi: bb = New Byte[4] ' A titolo esemplificativo scrive 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 ' Con i "Memory Stream" scrive nell'area di memoria, puntata dalla Proprietà ".Data" del vettore usato, i dati contenuti dal "Puntatore" da dereferenziare: st = Memory bb.Data For Write Write #st, p, bb.Count ' Scrive una quantità definita di dati, contenuti dal "Puntatore" [nota 3] st.Close ' Verifica il risultato: 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
Uso del membro "void *data" della Struttura costitutiva dell'Oggetto "Array" di Gambas
La dereferenziazione di un Puntatore utilizzando il membro "void *data" della Struttura, costitutiva dell'Oggetto "Array" di Gambas, è procedura abbastanza complessa. [nota 4]
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 essendo costitutiva dell'Oggetto "Array" del linguaggio 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 quantità 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 scrive 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 ' Ottiene l'indirizzo di memoria del vettore - come Oggetto [nota 5] - mediante il Metodo "Object.Address()" (in tal modo penetra 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", si sposta all'interno di quell'area di memoria appunto al byte di indice 32: ind = pv + 32 ' Con i "Memory Stream" scrive 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 ' Verifica 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] Per questa scrittura dei dati in un flusso, contenuti nell'area di memoria puntata da un Puntatore, vedasi la seguente pagina: Scrivere in un file i dati contenuti in un'area di memoria puntata da un Puntatore
[4] Al riguardo vedasi anche questo paragrafo: Assegnando il Puntatore al membro Data della Struttura CARRAY dei sorgenti di Gambas
[5] 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.