Oh so! Thank you Steve. As i see to this code, so ELEMENTSIZE can be used also for arrays created with TYPE without worrying about how many bytes in memory a particular element occupies?
Here's an example of how _MEM works with User Defined Types. See if it makes sense to you:
TYPE Any_Type
X AS INTEGER
Y AS INTEGER
Junk AS STRING * 25
END TYPE
DIM array(100) AS Any_Type 'an array of our user type
DIM M AS _MEM 'a mem block
M = _MEM(array()) 'pointed to the array()
_MEMPUT M, M.OFFSET, 1001 AS INTEGER 'start at M.offset for byte 0
_MEMPUT M, M.OFFSET + 2, 9876 AS INTEGER '2 bytes over is where our integer is located
_MEMPUT M, M.OFFSET + 4, "Hello World" 'and 2 bytes over from there is where the string info starts at
PRINT array(0).X, array(0).Y, array(0).Junk
_MEMPUT M, M.OFFSET + M.ELEMENTSIZE, 5000 AS INTEGER 'array(1); same elements
_MEMPUT M, M.OFFSET + M.ELEMENTSIZE + 2, 1234 AS INTEGER
_MEMPUT M, M.OFFSET + M.ELEMENTSIZE + 4, "Goodbye World"
PRINT array(1).X, array(1).Y, array(1).Junk
temp$ = MKI$(7777) + MKI$(3333) + "What the what???" 'array(2) -- ALL AT ONCE
_MEMPUT M, M.OFFSET + M.ELEMENTSIZE * 2, temp$ 'notice how M.ElementSize helps us position ourselves to the start of the array element we're looking for?
PRINT array(2).X, array(2).Y, array(2).Junk
_MEMPUT M, M.OFFSET + M.ELEMENTSIZE * 3, "00" '256 written in ASCII characters, then 512 written in ASCII characters
_MEMPUT M, M.OFFSET + M.ELEMENTSIZE * 3 + 4, "Numeric values written as Strings?"
PRINT array(3).X, array(3).Y, array(3).Junk
PRINT array(4).X, array(4).Y, array(4).Junk 'notice how we put values into array element 3 AND 4 with the last print statement? It was too large to fit in the STRING * 25 which I'd defined, so it carried over and corrupted the next array index.
If you notice, QB64 doesn't give a hoot about what we put into memory with _MEMPUT. (The last example should make that perfectly clear, I'd think.) When it comes to TYPEs, all it basically tracks for us is the size of the type, and where the elements start at. It's up to you to know your offsets and define them somehow for use in your programs (look at my QBDbase routines and you can see where they do that so we can use _MEM with whatever type a user has). When you _MEMGET or _MEMPUT, you specify what type of variable you expect to get and put into that position in memory, but there's no real requirement forcing you to only put/get a certain type.
Compare it to the following:
OPEN "temp.txt" for BINARY AS #1
a$ = chr$(1)+chr$(2)
PUT #1, 1, a$
DIM b as _UNSIGNED _BYTE
Get #1, 1, b
PRINT b
GET #1, 2, b
PRINT b
You put a string in your file, but then read it as 2 bytes...
You could also read that value as an integer, if you wanted: GET #1, 1, x%
Once it's in the file, your file doesn't care what the information is you stored. It just stores the information you put into it, where you decided to put it. _MEM works the exact same way.
Sometimes, you just have to manually track some of that information for yourself (espcially with user types). ;)
And in case the auto-format screws things up, this line should look like so:
_MEMPUT M, M.OFFSET + M.ELEMENTSIZE * 3, "00" '256 written in ASCII characters, then 512 written in ASCII characters
(That's CHR$(1) + "0" + CHR$(2) + "0", in case all else fails to format it properly.)