Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Bug when redimensioning multi-dimension arrays?
#5
(06-19-2024, 10:36 PM)TerryRitchie Wrote: Yep, this a known issue. I'll let Steve explain it in detail though. He explained it to me a few years back when I was wondering the same thing but I can't seem to find that explanation now? It may have been on a previous forum.

The details...    ..by Steve(tm)!!  Big Grin

What's happening here really isn't that hard to understand.  Even though that's a 2-dimensional array, how do you think it's stored in memory?  Is there a 2-dimensional block of memory somewhere?   Does 3-dimensional arrays get stored in 3-dimensional RAM blocks?   Are 4-dimensional arrays only available in quanturm 4-D computers?

Tongue

Nope.   All of these are stored in a single, contigious block of memory.    You may have a 3x3 array which looks like this:

1, 4, 7
2, 5, 8
3, 6, 9

But, in memory, it's going to look like:  1, 2, 3, 4, 5, 6, 7, 8, 9

Now, how does preserve work??

It copies that continious block of memory and simple moves it over to the new sized array.    Make a 5 x 3 array, and it creates it to look like:

0, 0, 0
0, 0, 0
0, 0, 0
0, 0, 0
0, 0, 0

And then it copies those 9 items from the old over to the start of that new array:

1, 6, 0
2. 7. 0
3, 8, 0
4, 9, 0
5, 0, 0

And you take a look at that and go....  WHUT??   My array is all scrambled now!   Index don't match!!

And they don't, though the data is still in the same order, the index now aren't...

BUT, let's take a look at what happens if you resize on the other index -- making 3 x 5 array:

First, the new array:

0, 0, 0, 0, 0
0, 0, 0, 0, 0
0, 0, 0, 0, 0

And then we copy that block of memory over:
1, 4, 7, 0, 0
2, 5, 8, 0, 0
3, 6, 9, 0, 0

Those indexes still match up, and the data is still in the same order!



So, when using REDIM _PRESERVE, one can resize on the LAST index only, and have the data stay in place and organized.  Otherwise, the indexes get scrambled (the data still stays in one block, but the indexes to that block no longer match the same format).

To ReDIm an array on 2/3/4/n-dimensions, you'll need to write your own routine for that.

First, create a new array:

REDIM Temp (y_old_size, x_old_size) AS TYPE

Then transfer the values over:

FOR y = 0 to old_y_limit
   FOR x = 0 TO old_x_limit
      Temp(y, x) = Old_Array(y, x)
NEXT x, y

Then resize the old array:

REDIM Old_Array(new_y, new_x) AS TYPE

And transfer the values back over:

FOR y = 0 to old_y_limit
   FOR x = 0 TO old_x_limit
      Old_Array(y, x) = Temp(y, x)
NEXT x, y

And you're done!

(If not in a SUB/Function which cleans up variables at exit, you may want to REDIM Temp(0,0) AS TYPE to reduce memory usage and clean up that temp array to as small a footprint as possible.)
Reply


Messages In This Thread
RE: Bug when redimensioning multi-dimension arrays? - by SMcNeill - 06-20-2024, 02:07 AM



Users browsing this thread: 11 Guest(s)