Differenze tra le versioni di "Assegnare ad un vettore i valori contenuti da un'area di memoria puntata da un Puntatore"

Da Gambas-it.org - Wikipedia.
Riga 75: Riga 75:
 
      
 
      
 
   Free(p)
 
   Free(p)
 +
 
 +
'''End'''
 +
 +
 +
 +
===Assegnando il ''Puntatore'' al membro ''Data'' della Struttura ''CARRAY'' dei sorgenti di Gambas===
 +
Un'altra modalità, più complessa, è quella di assegnare il ''Puntatore'' al membro ''data'' della Struttura ''CARRAY'' dei sorgenti di Gambas.
 +
 +
La Struttura ''CARRAY'' presente nel file header ''gbx_c_array.h'' dei sorgenti di Gambas è così definita:
 +
typedef
 +
        Struct {
 +
OBJECT object;
 +
int size;
 +
int count;
 +
TYPE type;
 +
<FONT Color=#B22222>void * data</font>;
 +
int * Dim ;
 +
void * ref;
 +
}
 +
CARRAY;
 +
laddove in particolare il membro:
 +
* '''''size''''' è un intero che rappresenta la ''dimensione'' dei valori contenuti dal vettore (ossia è il ''tipo'' di valori del vettore);
 +
* '''''count'''' è un intero che rappresenta il numero di elementi costituenti il vettore;
 +
* '''''data''''' è un Puntatore all'area di memoria riservata che contiene i dati contenuti dal vettore.
 +
 +
Pertanto, nel codice che appronteremo, bisognerà:
 +
<BR>1) cambiare, qualora il numero di elementi del vettore sia diverso dalla dimensione dell'area puntata dal Puntatore (tenuto conto ovviamente dal <SPAN Style="text-decoration:underline">tipo</span> di valori), il valore presente nel membro ''count'', assegnandogli il valore corrispondente al nuovo numero di elementi che il vettore dovrà possedere;
 +
<BR>2) cambiare il valore del ''Puntatore'' all'area di memoria dei dati presente nel membro ''data'', assegnando il nuovo ''Puntatore''.
 +
 +
Sarà opportuno, al fine di evitare errori di memoria, chiudere il programma con la funzione esterna di C: ''exit()'' .
 +
 +
Mostriamo di seguito un esempio pratico:
 +
<FONT Color=gray>' ''void exit(int status)ìì
 +
' ''Terminates the calling process immediately. Any open file descriptors belonging to the process are closed.''</font>
 +
Private Extern C_exit(status As Integer) In "libc:6" Exec "exit"
 +
 +
 +
'''Public''' Sub Main()
 +
 +
  Dim bb As New Byte[]
 +
  Dim pbb, count, dati, p As Pointer
 +
  Dim st As Stream
 +
  Dim b, n As Byte
 +
 
 +
<FONT Color=gray>' ''Ipotizziamo una situazione iniziale con un vettore contenente 5 elementi, tutti aventi un dato valore:''</font>
 +
  bb = [11, 222, 33, 44, 55]
 +
 +
<FONT Color=gray>' ''Allochiamo 64 byte di area di memoria riservata, e la puntiamo con un "Puntatore":''</font>
 +
  p = Alloc(64)
 +
   
 +
<FONT Color=gray>' ''Azzeriamo i byte dell'area di memoria precedentemente allocata, ma salvaguardando i valori preesistenti del vettore:''</font>
 +
  st = Memory p For Write
 +
  For b = 0 To 63
 +
    n = 0
 +
    If b <= bb.Max Then n = bb[b]
 +
    Write #st, n As Byte
 +
  Next
 +
  st.Close
 +
 
 +
<FONT Color=gray>' ''Verifichiamo semplicemente il numero iniziale del numero degli elementi del vettore:''</font>
 +
  Print bb.Count
 +
 
 +
  Print "---------------------------------------------\n"
 +
 
 +
<FONT Color=gray>' ''Accediamo alla "Struttura" interna dell'oggetto "array" (il vettore dichiarato "bb") di Gambas:''</font>
 +
  pbb = Object.Address(bb)
 +
 
 +
<FONT Color=gray>' ''Accediamo al membro "count" della predetta "Struttura" interna del vettore "bb":''</font>
 +
  count = pbb + 20
 +
 
 +
<FONT Color=gray>' ''Accediamo al membro "data" della predetta "Struttura" interna del vettore "bb":''</font>
 +
  dati = pbb + 32
 +
 
 +
<FONT Color=gray>' ''Impostiamo il nuovo numero di elementi che il vettore "bb" possiederà:''</font>
 +
  st = Memory count For Write
 +
  Write #st, 64 As Integer  <FONT Color=gray>' ''Scriviamo "As Integer", poiché il membro "count" è un intero a 32 bit''</font>
 +
  st.Close
 +
 
 +
<FONT Color=gray>' ''Verifichiamo il numero degli elementi del vettore dopo l'assegnazione del nuovo valore al membro "count" della "Struttura" interna del vettore "bb":''</font>
 +
  Print bb.Count
 +
 
 +
<FONT Color=gray>' ''Assegnamo il nuovo "Puntatore"al membro "data" della "Struttura" interna del vettore "bb":''</font>
 +
  st = Memory dati For Write
 +
  Write #st, p As Pointer
 +
  st.Close
 +
  Free(p)
 +
 
 +
<FONT Color=gray>' ''Usiamo dunque la nuova attribuzione di area di memoria e di elementi al vettore "bb":''</font>
 +
  bb[10] = 21
 +
  bb[27] = 8
 +
  bb[39] = 19
 +
  bb[54] = 69
 +
 
 +
<FONT Color=gray>' ''Verifichiamo i valori presenti nel vettore "bb":''</font>
 +
  For b = 0 To bb.Max
 +
    Print b, bb[b]
 +
  Next
 +
 
 +
<FONT Color=gray>' ''Chiudiamo con sicurezza il programma, liberando tutta la memoria utilizzata per esso:''</font>
 +
  C_exit(0)
 
    
 
    
 
  '''End'''
 
  '''End'''

Versione delle 13:38, 12 mar 2016

Per assegnare ad un vettore i valori contenuti da un'area di memoria puntata da un Puntatore, è possibile adottare almeno due modalità.


Uso delle funzioni di Gambas di dereferenziazione dei Puntatori

La prima modalità prevede di assegnare ad ogni elemento del vettore i valori dell'area di memoria riservata, puntata dal Puntatore, dereferenziando man mano il Puntatore medesimo.

Mostriamo un semplice esempio pratico:

Public Sub Main()
 
 Dim p As Pointer
 Dim st As Stream
 Dim b As Byte
 Dim bb As New Byte[]
 
' Allochiamo un'area di memoria riservata pari ad 8 byte:
  p = Alloc(8)
  
' Ai fini di questo esempio scriviamo alcuni dati nell'area di memoria allocata:
  st = Memory p For Write
  For b = 1 To 8
    Write #st, b * 10 As Byte
  Next
  st.Close
   
' Assegnamo agli elementi del vettore i valori presenti nell'area di memoria allocata:
  For b = 0 To 7
    bb.Push(Byte@(p + CInt(b)))
  Next
   
' Verifichiamo in console l'assegnamento:
  For Each b In bb
    Print b
  Next
   
  Free(p)
  
End


Uso della funzione esterna memcpy() di C

Possiamo anche utilizzare la funzione esterna memcpy() di C, richiamando la libreria libc.so.6 . Mostriamo un semplice esempio pratico:

Library "libc:6"

' void *memcpy (void * __dest, const void * __src, size_t __n)
' Copy N bytes of SRC to DEST.
Private Extern memcpy(dest As Pointer, __src As Pointer, n As Long) As Pointer


Public Sub Main()
 
 Dim p As Pointer
 Dim st As Stream
 Dim b As Byte
 Dim bb As New Byte[8]
 
' Allochiamo un'area di memoria riservata pari ad 8 byte:
  p = Alloc(8)
  
' Ai fini di questo esempio scriviamo alcuni dati nell'area di memoria allocata:
  st = Memory p For Write
  For b = 1 To 8
    Write #st, b * 10 As Byte
  Next
  st.Close
   
' Con la funzione esterna "memcpy()" copiamo nel vettore gli 8 valori presenti nell'area di memoria allocata:
  memcpy(bb.Data, p, 8)
   
' Verifichiamo in console l'assegnamento:
  For Each b In bb
    Print b
  Next
   
  Free(p)
  
End


Assegnando il Puntatore al membro Data della Struttura CARRAY dei sorgenti di Gambas

Un'altra modalità, più complessa, è quella di assegnare il Puntatore al membro data della Struttura CARRAY dei sorgenti di Gambas.

La Struttura CARRAY presente nel file header gbx_c_array.h dei sorgenti di Gambas è così definita:

typedef
       Struct {
		OBJECT object;
		int size;
		int count;
		TYPE type;
		void * data;
		int * Dim ;
		void * ref;
		}
	CARRAY;

laddove in particolare il membro:

  • size è un intero che rappresenta la dimensione dei valori contenuti dal vettore (ossia è il tipo di valori del vettore);
  • count' è un intero che rappresenta il numero di elementi costituenti il vettore;
  • data è un Puntatore all'area di memoria riservata che contiene i dati contenuti dal vettore.

Pertanto, nel codice che appronteremo, bisognerà:
1) cambiare, qualora il numero di elementi del vettore sia diverso dalla dimensione dell'area puntata dal Puntatore (tenuto conto ovviamente dal tipo di valori), il valore presente nel membro count, assegnandogli il valore corrispondente al nuovo numero di elementi che il vettore dovrà possedere;
2) cambiare il valore del Puntatore all'area di memoria dei dati presente nel membro data, assegnando il nuovo Puntatore.

Sarà opportuno, al fine di evitare errori di memoria, chiudere il programma con la funzione esterna di C: exit() .

Mostriamo di seguito un esempio pratico:

' void exit(int status)ìì
' Terminates the calling process immediately. Any open file descriptors belonging to the process are closed.
Private Extern C_exit(status As Integer) In "libc:6" Exec "exit"


Public Sub Main()

 Dim bb As New Byte[]
 Dim pbb, count, dati, p As Pointer
 Dim st As Stream
 Dim b, n As Byte
 
' Ipotizziamo una situazione iniziale con un vettore contenente 5 elementi, tutti aventi un dato valore:
  bb = [11, 222, 33, 44, 55]

' Allochiamo 64 byte di area di memoria riservata, e la puntiamo con un "Puntatore":
  p = Alloc(64)
   
' Azzeriamo i byte dell'area di memoria precedentemente allocata, ma salvaguardando i valori preesistenti del vettore:
  st = Memory p For Write
  For b = 0 To 63
    n = 0
    If b <= bb.Max Then n = bb[b]
    Write #st, n As Byte
  Next
  st.Close
  
' Verifichiamo semplicemente il numero iniziale del numero degli elementi del vettore:
  Print bb.Count
  
  Print "---------------------------------------------\n"
  
' Accediamo alla "Struttura" interna dell'oggetto "array" (il vettore dichiarato "bb") di Gambas:
  pbb = Object.Address(bb)
  
' Accediamo al membro "count" della predetta "Struttura" interna del vettore "bb":
  count = pbb + 20
  
' Accediamo al membro "data" della predetta "Struttura" interna del vettore "bb":
  dati = pbb + 32
  
' Impostiamo il nuovo numero di elementi che il vettore "bb" possiederà:
  st = Memory count For Write
  Write #st, 64 As Integer   ' Scriviamo "As Integer", poiché il membro "count" è un intero a 32 bit
  st.Close
  
' Verifichiamo il numero degli elementi del vettore dopo l'assegnazione del nuovo valore al membro "count" della "Struttura" interna del vettore "bb":
  Print bb.Count
  
' Assegnamo il nuovo "Puntatore"al membro "data" della "Struttura" interna del vettore "bb":
  st = Memory dati For Write
  Write #st, p As Pointer
  st.Close
  Free(p)
  
' Usiamo dunque la nuova attribuzione di area di memoria e di elementi al vettore "bb":
  bb[10] = 21
  bb[27] = 8
  bb[39] = 19
  bb[54] = 69
  
' Verifichiamo i valori presenti nel vettore "bb":
  For b = 0 To bb.Max
    Print b, bb[b]
  Next
  
' Chiudiamo con sicurezza il programma, liberando tutta la memoria utilizzata per esso:
  C_exit(0)
  
End