The memory for a two-dimensional
array is laid out the same way as a single dimensional array,
except that the "rows" are contiguous. For example,
if you write
Dim ar(1,3)
in memory you would find all the elements,
contiguously, in this order:
ar(0,0) -- ar(1,0) -- ar(0,1) -- ar(1,1)
-- ar(0,2) -- ar(1,2) -- ar(0,3) -- ar(1,3).
To find element ar(x,y), you can treat
this as a single dimensioned array and find the element numbered
as:
y * ( UBOUND(ar,1) + 1 ) + x
That is, ar(1,2) -->> 2 * ( UBound(ar,1)+1
) + 1 -->> 2 * 2 + 1 -->> element number 5 [starting
at 0, of course].
If you count to element number 5 in
the above code, you will see that it is, indeed, ar(1,2).
Thus, to get the address of that element,
you simply multiply that result by 16 and add it to the address
of the start of the array.
Why is this scheme chosen by VBScript?
Simply so that ReDim Preserve is easier to implement.
Suppose you start with that array above,
and then do ReDim Preserve ar(1,5). First, enough memory for the
new array: 16 * 2 * 6 bytes (128 bytes) is allocated. Then it simply
copies the old array (beginning at its starting address) to the starting
address of the new array. (NOTE: The elements of the new array
beyond the end of the old need to be zeroed out.) If it created the
memory layout any other way, ReDim Preserve would be a lot more work.
Note that none of the elements in the newly sized array need be touched.
Pointers to objects (including strings) are still pointing to the
right place. Primitive values (numbers, etc.), of course, can still
be used.