Array as overlay
-
- Posts: 284
- Joined: Mar 07, 2018 13:59
- Location: Germany
Array as overlay
I have a set of data in a string, which is arranged in an array like manner. In PowerBASIC i can do a "DIM ...AT ..." to create an array, which is in fact an overlay over the existing data. That is, the data isn´t initialized as usual, but the existing data at the specified address remains untouched and now can be accessed via this array. The basic concept is like an UNION but extended to an array, different variables known to the compiler with different data types share the same memory.
Example:
Let´s say "address" is a pointer to my data, i dim an array of longs (4 bytes each), and i give a lbound of 1 and a ubound of 10 (dim myarray(1 to 10) as long at address), then i would have the the first 4 bytes of my data in myarray(1), the next 4 bytes in myarray(2) and so on.
How can i do this FreeBASIC? This should work for UDTs too!
JK
Example:
Let´s say "address" is a pointer to my data, i dim an array of longs (4 bytes each), and i give a lbound of 1 and a ubound of 10 (dim myarray(1 to 10) as long at address), then i would have the the first 4 bytes of my data in myarray(1), the next 4 bytes in myarray(2) and so on.
How can i do this FreeBASIC? This should work for UDTs too!
JK
-
- Posts: 862
- Joined: May 05, 2015 5:35
- Location: Germany
Re: Array as overlay
You could abuse a ZString Ptr: It's important to use a var-len string for the data, because a ZString terminates at the first 0 byte.
Code: Select all
Dim As String g = "abcd" + Chr(0,0,0,0) + "ijklmnop"
Dim As ZString*20 h = "abcd" + Chr(0,0,0,0) + "ijklmnop"
Dim As Integer a(1 To 4), b(1 To 4)
For x As Integer = 1 To 4
Print a(x)
Next
Print
*Cast(ZString Ptr, @a(1)) = g
For x As Integer = 1 To 4
Print a(x)
Next
Print
*Cast(ZString Ptr, @b(1)) = h
For x As Integer = 1 To 4
Print b(x)
Next
Sleep
Re: Array as overlay
Dim byref is not defined for arrays, only for single instances of a datatype
but for arrays inside a udt it works
but for arrays inside a udt it works
Code: Select all
Type udt
Dim As String g(1 To 10)
End Type
Dim As udt s
For n As Long=1 To 10
s.g(n)=Str(n)+" Hello"
Print @s.g(n),s.g(n)
Next
Print
Dim Byref As udt s2=s
For n As Long=1 To 10
Print @s2.g(n),s2.g(n)
Next
Sleep
Re: Array as overlay
@grindstone
That code does not work on 64bit machines. If it works on 32bit, how do you get from a(x) back to a string?
@dodicat
I don't think that is what juergen kuehiwein is wanting.
It seems you are simply copying two arrays.
If I am not mistaken he wants something that can take the string containing "hello" and return an array where
a(1) = "h", a(2) = "e", a(3) = "l" etc. And by simply moving memory or pointer; not by copying char by char.
Or a string containing "abcdefghijklmnop" and return an array containing 4 x string * 4 members.
That code does not work on 64bit machines. If it works on 32bit, how do you get from a(x) back to a string?
@dodicat
I don't think that is what juergen kuehiwein is wanting.
It seems you are simply copying two arrays.
If I am not mistaken he wants something that can take the string containing "hello" and return an array where
a(1) = "h", a(2) = "e", a(3) = "l" etc. And by simply moving memory or pointer; not by copying char by char.
Or a string containing "abcdefghijklmnop" and return an array containing 4 x string * 4 members.
-
- Posts: 1002
- Joined: Jul 14, 2005 23:41
Re: Array as overlay
Here is a starting point. I stole it from someone in this forum (fxm?)
Code: Select all
TYPE EMPLOYEE
empName AS STRING
empAddress AS STRING
empSalary AS DOUBLE
END TYPE
' Create a generaic block of memory
dim pMem as any ptr = CALLOCATE( 1024)
' Here is the DIM AT syntax. Notice the NEW(pMem) part.
' Basically 10 new employee TYPE's are overlayed on the
' existing pMem area.
DIM pEmp AS EMPLOYEE Ptr = NEW(pMem) EMPLOYEE[10]
' Assign data to our employee
pEmp->empName = "Paul"
pEmp->empAddress = "Canada"
pEmp->empSalary = 10000000.00
? pEmp->empName
? pEmp->empAddress
? pEmp->empSalary
' Deallocate our memory
DEALLOCATE(pMem)
sleep
Re: Array as overlay
No, it's not my style.PaulSquires wrote:I stole it from someone in this forum (fxm?)
In addition, I do not see the benefit of defining objects at a specified memory buffer address if these objects contain string descriptors.
@Juergen Kuehlwein,
Can you complete your request with a more precise example?
Re: Array as overlay
But from what I understand (proposal with indexing pointer):
Little variant:
With index base = 1 everywhere:
Code: Select all
Dim As String * 16 txt = "ABCDEFGHIJKLMNOP"
Union UDT
Dim As Short s
Type
Dim As Ubyte u0
Dim As Ubyte u1
Dim As Ubyte u2
Dim As Ubyte u3
End Type
End Union
Dim As UDT Ptr p = Cptr(UDT Ptr, @txt)
Print txt
Print
For I As Integer = 0 To 3
Print p[I].s,
Print p[I].u0 & ":" & Chr(p[I].u0),
Print p[I].u1 & ":" & Chr(p[I].u1),
Print p[I].u2 & ":" & Chr(p[I].u2),
Print p[I].u3 & ":" & Chr(p[I].u3)
Next I
Sleep
Code: Select all
Dim As String * 16 txt = "ABCDEFGHIJKLMNOP"
Union UDT
Dim As Short s
Type
Dim As Ubyte u(0 To 3)
End Type
End Union
Dim As UDT Ptr p = Cptr(UDT Ptr, @txt)
Print txt
Print
For I As Integer = 0 To 3
Print p[I].s,
For J As Integer = 0 To 3
Print p[I].u(J) & ":" & Chr(p[I].u(J)),
Next J
Print
Next I
Sleep
Code: Select all
Dim As String * 16 txt = "ABCDEFGHIJKLMNOP"
Union UDT
Dim As Short s
Type
Dim As Ubyte u(1 To 4)
End Type
End Union
Dim As UDT Ptr p = Cptr(UDT Ptr, @txt) - 1
Print txt
Print
For I As Integer = 1 To 4
Print p[I].s,
For J As Integer = 1 To 4
Print p[I].u(J) & ":" & Chr(p[I].u(J)),
Next J
Print
Next I
Sleep
-
- Posts: 862
- Joined: May 05, 2015 5:35
- Location: Germany
Re: Array as overlay
I can't help the 64bit issue due to lack of 64bit here.sancho3 wrote:@grindstone
That code does not work on 64bit machines. If it works on 32bit, how do you get from a(x) back to a string?
The pointer acrobatics for the reverse conversion is a little more tricky :
Code: Select all
'string to array
Dim As String g = "abcd" + Chr(0,0,0,0) + "ijklmnop"
Dim As ZString*20 h = "abcd" + Chr(0,0,0,0) + "ijklmnop"
Dim As Integer a(1 To 4), b(1 To 4)
For x As Integer = 1 To 4
Print a(x)
Next
Print
*Cast(ZString Ptr, @a(1)) = g
For x As Integer = 1 To 4
Print a(x)
Next
Print
*Cast(ZString Ptr, @b(1)) = h
For x As Integer = 1 To 4
Print b(x)
Next
'array to string
Dim As String s, t
Dim As UByte Ptr remember
Dim As Integer Ptr ip
t = String(SizeOf(a) * (UBound(a) - LBound(a) + 1), Chr(0)) 'create a string matching the array's memory size
ip = Cast(Integer Ptr, @t) 'get the pointer to the string descriptor of t
remember = Cast(UByte Ptr, *ip) 'save the pointer to the original text of t
*ip = Cast(Integer, @a(1)) 'replace the text pointer of t with the array pointer
s = t 'copy the array content as string
*ip = Cast(Integer, remember) 'restore the original text pointer of t
Print
Print s
Sleep
Last edited by grindstone on Jan 08, 2019 10:19, edited 1 time in total.
-
- Posts: 284
- Joined: Mar 07, 2018 13:59
- Location: Germany
Re: Array as overlay
sancho3 got it! Of course i could fill any array with data element by element, but i want to do it in one go without making intermediate copies.
NEW(Placement) is the key - thanks Paul
Thanks to all
JK
NEW(Placement) is the key - thanks Paul
Code: Select all
dim n as long
dim z as zstring ptr
dim b() as byte
redim b(1 to 17)
z = new(@b(1)) byte[17]
*z = "Hello " + chr(0) + "everybody"
for n = 1 to 17
print b(n) & !"\t - " & chr(b(n))
next n
sleep
JK
-
- Posts: 284
- Joined: Mar 07, 2018 13:59
- Location: Germany
Re: Array as overlay
grindstone,
we cross posted - thanks!
does essentially the same, but is more compact, i like it!
JK
we cross posted - thanks!
Code: Select all
*Cast(ZString Ptr, @a(1)) = g
JK
Re: Array as overlay
Your question was the opposite that I thought (and therefore simpler):
How to overlay a zstring buffer on an array 1D?
Note: if you resize the array after in the code, its address may change.
z = new(@b(1)) byte[17]
with:
z = @b(1)
How to overlay a zstring buffer on an array 1D?
Note: if you resize the array after in the code, its address may change.
No, you can simplify:Juergen Kuehlwein wrote:NEW(Placement) is the key
z = new(@b(1)) byte[17]
with:
z = @b(1)
-
- Posts: 284
- Joined: Mar 07, 2018 13:59
- Location: Germany
Re: Array as overlay
Indeed my initial question was how to overlay an array on a (z)string buffer. But in this case the order is meaningless for the result. If it´s easier to overlay a zstring on an array than the other way round, then let´s do it.Your question was the opposite that I thought (and therefore simpler):
How to overlay a zstring buffer on an array 1D?
I realized that i don´t need "NEW" here, using pointers does the trick.
Thanks
JK
Re: Array as overlay
Well, I have been messing around trying to overlay a block of memory used by a string by an array.
Now you opt for the reverse.
OK, I didn't read your first post correctly initially and I used a byref with a udt.
Then I did read your first post and was trying resolve the request, but unfortunately I didn't read your last post (The switch).
Hardly worth putting in a feature request probably, but for things like overlaying chunks of memory an array of references should be supported.
at the moment we get
Array of references - not supported yet
So all hinges on the yet bit.
Anyway now I now have a memory block in my head so I am off for a cup of tea.
Now you opt for the reverse.
OK, I didn't read your first post correctly initially and I used a byref with a udt.
Then I did read your first post and was trying resolve the request, but unfortunately I didn't read your last post (The switch).
Hardly worth putting in a feature request probably, but for things like overlaying chunks of memory an array of references should be supported.
at the moment we get
Array of references - not supported yet
So all hinges on the yet bit.
Anyway now I now have a memory block in my head so I am off for a cup of tea.
Re: Array as overlay
Instead of overlaying a 1D array, why not just use the string index operator (specific FreeBASIC keyword that returns the indexed byte value) that looks like a 1D array:
Code: Select all
dim z as zstring * 16+1 = "Hello " + chr(0) + "everybody"
for n as integer = 0 to 16
print z[n] & !"\t - " & chr(z[n])
next n
sleep
-
- Posts: 284
- Joined: Mar 07, 2018 13:59
- Location: Germany
Re: Array as overlay
Well, sorry - sometimes everyone of us tends to approach a problem with a specific solution in mind (just because this kind of solution worked elsewhere). This mind set prevents you from taking a step back.Now you opt for the reverse
The solution here is so easy, if you just do it the other way round. But it took me some time to realize this!
why not just use the string index operator
It should work for all kinds of arrays, not only for my simplified example.
Thanks again - problem solved
JK