Author Topic: REDIM _PRESERVE bug  (Read 7869 times)

0 Members and 1 Guest are viewing this topic.

This topic contains a post which is marked as Best Answer. Press here if you would like to see it.

Offline TerryRitchie

  • Seasoned Forum Regular
  • Posts: 495
  • Semper Fidelis
    • View Profile
REDIM _PRESERVE bug
« on: March 28, 2020, 05:00:32 pm »
Is there any time line on when this bug may get corrected? I really need to be able to preserve values across multi-dimensional arrays.

Code: QB64: [Select]
  1. 'REDIM _PRESERVE bug in multiple dimensioned arrays.
  2.  
  3.  
  4. REDIM Test(0, 0)
  5.  
  6.  
  7. FOR i = 0 TO 9
  8.     Test(0, i) = i
  9.     PRINT Test(0, i)
  10.     REDIM _PRESERVE Test(0, UBOUND(test, 2) + 1)
  11.  
  12. FOR i = 0 TO 9
  13.     PRINT Test(0, i)
  14. PRINT "That works. But when you REDIM the other index this happens."
  15. REDIM _PRESERVE Test(1, UBOUND(Test, 2))
  16. FOR i = 0 TO 9
  17.     PRINT Test(0, i), Test(1, i)
  18. PRINT "The values get spread across both indexes."
In order to understand recursion, one must first understand recursion.

FellippeHeitor

  • Guest
Re: REDIM _PRESERVE bug
« Reply #1 on: March 28, 2020, 08:10:10 pm »
That's an out-of-my-league issue. Luke assigned it to himself on the repo, but Luke has a life outside QB64 realm, so... no idea.

Offline STxAxTIC

  • Library Staff
  • Forum Resident
  • Posts: 1091
  • he lives
    • View Profile
Re: REDIM _PRESERVE bug
« Reply #2 on: March 28, 2020, 08:16:31 pm »
This is why I wish I started working on a really nice linked list library like a year ago. I have yet to develop this thought properly, but I suspect that linked lists can get us around this redim problem, and god willing, *all* problems surrounding arrays: mixing types and so on. I already use the technique on a case-by-case basis when I have a program that really demands a lot of its data - namely 3D levels and text editing to name my big two.

Anyway, see if linked lists work for you Terry. It's gonna have to be all hand-rolled but the power tradeoff is hands-down better when you need it.

EDIT: By the way your signature is hilarious!
« Last Edit: March 28, 2020, 08:19:51 pm by STxAxTIC »
You're not done when it works, you're done when it's right.

Offline TerryRitchie

  • Seasoned Forum Regular
  • Posts: 495
  • Semper Fidelis
    • View Profile
Re: REDIM _PRESERVE bug
« Reply #3 on: March 28, 2020, 08:30:10 pm »
That's an out-of-my-league issue. Luke assigned it to himself on the repo, but Luke has a life outside QB64 realm, so... no idea.

Ok, I do understand that life does take precedence and Luke has one too :-)  I'll start investigating the method STxAxTIC pointed out. Thank you for the reply Fellippe.

By the way Fellippe, I am absolutely astonished that you wrote something as complex as InForm without the need for dynamic multi-dimensional arrays!
« Last Edit: March 28, 2020, 08:36:22 pm by TerryRitchie »
In order to understand recursion, one must first understand recursion.

Offline TerryRitchie

  • Seasoned Forum Regular
  • Posts: 495
  • Semper Fidelis
    • View Profile
Re: REDIM _PRESERVE bug
« Reply #4 on: March 28, 2020, 08:40:26 pm »
Luke, if you happen to read this and get the issue resolved there's a month's worth of your favorite beverage on the way .. Starbucks?  A case of YooHoo? :-)))
In order to understand recursion, one must first understand recursion.

Marked as best answer by TerryRitchie on March 28, 2020, 05:20:34 pm

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: REDIM _PRESERVE bug
« Reply #5 on: March 28, 2020, 09:14:41 pm »
It's not really a bug, as it is a set limitation to how REDIM works.  I did a video explaining the whole process and how it all works behind the scenes here:


If one needs to REDIM and preserve beyond the first index, then they just need to write their own routine to handle it.

SUB CustomRedim (Original2DArray(), NewIndex1, NewIndex2)
    DIM Temp(NewIndex1, NewIndex2)
    FOR X = 0 to NewIndex1
        FOR Y = 0 TO NewIndex2
           If X <= UBOUND(Original2DArray, 2) and Y <= UBOUND(Original2DArray, 1) THEN Temp(X, Y) = Original2DArray(X, Y)
       NEXT
    NEXT
    REDIM Original2DArray(NewIndex1, NewIndex2)
    Original2DArray() = Temp()
END SUB
   
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline TerryRitchie

  • Seasoned Forum Regular
  • Posts: 495
  • Semper Fidelis
    • View Profile
Re: REDIM _PRESERVE bug
« Reply #6 on: March 28, 2020, 09:21:44 pm »
Bam, Steve to the rescue. I was just sitting here contemplating the best method for rolling my own REDIM and Steve shows up with the solution.
In order to understand recursion, one must first understand recursion.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: REDIM _PRESERVE bug
« Reply #7 on: March 28, 2020, 10:25:00 pm »
I hate to rain on parades but this can't be done in QB64

Code: QB64: [Select]
  1. Original2DArray() = Temp()

We went over this when I explained the need to use MEM to copy arrays.
https://www.qb64.org/forum/index.php?topic=1695.msg109301#msg109301

Apparently the illustration didn't stick.
« Last Edit: March 28, 2020, 10:30:24 pm by bplus »

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: REDIM _PRESERVE bug
« Reply #8 on: March 28, 2020, 11:08:08 pm »
I hate to rain on parades but this can't be done in QB64

Code: QB64: [Select]
  1. Original2DArray() = Temp()

We went over this when I explained the need to use MEM to copy arrays.
https://www.qb64.org/forum/index.php?topic=1695.msg109301#msg109301

Apparently the illustration didn't stick.

I swear, I've did exactly this before.  Did the behavior change over time?  Does it only work in some situations?  I dunno!  Right now my PC is down again (bad power supply once again; the one Best Buy installed 6 months ago was 300watts smaller than the original -- SURPRISE!!  IT DIDN'T LAST!!)  Once Uncle Sam sends me my CoronaCash Stimulus $$$, I'm going to use it to get my PC fixed and a few upgrades installed in it (SSD, new video card, a proper sized power supply), and then I'll be back and actually coding again afterwards.  Maybe then I can sort out why my brain tells me X() = Y() works, and sort out why/when it doesn't for us.

If all else fails, just _MEMCOPY from one to the other (or use a series of FOR/NEXT loops to copy the data).  I'll add digging into the issue to my to do list, for when I'm able to type on something more substantial than my iPad, or notebook's crappy keyboard.  ;)
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

FellippeHeitor

  • Guest
Re: REDIM _PRESERVE bug
« Reply #9 on: March 29, 2020, 12:00:34 am »
In previous experiments, doing array1() = array2() in hopes of transferring their contents only resulted in the first element being copied. That wasn't recently.

Offline OldMoses

  • Seasoned Forum Regular
  • Posts: 469
    • View Profile
Re: REDIM _PRESERVE bug
« Reply #10 on: March 29, 2020, 06:10:41 am »
It didn't work for me just now. Good to know, I'll opt for _MEMCOPY if I have to do that.

Code: QB64: [Select]
  1. DIM A(10) AS INTEGER
  2. DIM B(10) AS INTEGER
  3. FOR x = 0 TO 10
  4.     A(x) = 10 - x
  5. B() = A()
  6. FOR y = 0 TO 10
  7.     PRINT A(y), B(y)
  8.  

Offline Petr

  • Forum Resident
  • Posts: 1720
  • The best code is the DNA of the hops.
    • View Profile
Re: REDIM _PRESERVE bug
« Reply #11 on: March 29, 2020, 07:05:38 am »
Why do you confuse the QB64 syntax and C syntax?

Code: QB64: [Select]
  1. DIM A(10) AS INTEGER
  2. DIM B(10) AS INTEGER
  3. FOR x = 0 TO 10
  4.     A(x) = 10 - x
  5.     B(x) = A(x)
  6.  
  7. FOR y = 0 TO 10
  8.     PRINT A(y), B(y)
  9.  

Offline OldMoses

  • Seasoned Forum Regular
  • Posts: 469
    • View Profile
Re: REDIM _PRESERVE bug
« Reply #12 on: March 29, 2020, 07:29:29 am »
Why do you confuse the QB64 syntax and C syntax?

Code: QB64: [Select]
  1. DIM A(10) AS INTEGER
  2. DIM B(10) AS INTEGER
  3. FOR x = 0 TO 10
  4.     A(x) = 10 - x
  5.     B(x) = A(x)
  6.  
  7. FOR y = 0 TO 10
  8.     PRINT A(y), B(y)
  9.  

Indeed, that is the way I would've normally done it before discovering MEM commands. I was just trying out the "bug", pointed out by bplus, for myself.

Offline TempodiBasic

  • Forum Resident
  • Posts: 1792
    • View Profile
Re: REDIM _PRESERVE bug
« Reply #13 on: March 29, 2020, 08:08:01 am »
Hi Guys
Hi Terry


in my little experience I have met this issue different times in coding when I've used an UDT ...

so you must remeber that REDIM PRESERVE works well only on a monodimensional array of a simple type data.
I have understood that the issue is around as the array has been packed into the memory... just like a stack so when you REDIM a multidimensional  array  your data seems spred among dimension of array, indeed they are simply stand into memory but we read the stack in different manner when  by changing the declaration of array ....
IMHO,saying that we have A(3,3,3) and we want to REDIM PRESERVE  A(4,5,2)the only solution is to write a manual SWAP routine that swaps the value from the first multidimensional array A(3,3,3) to a temporany multidimensional array B(4,5,2) and then copy this to the new dimensioned first array A(4,5,2).
As a alternative shortway you can REDIM 3 monodimensional array and then redim preserve them and at the end you store in the new dimensioned array....


you can see here some thread :

the original issue of PRESERVE  https://www.qb64.org/forum/index.php?topic=310.msg2155#msg2155
with the link to the thread on [abandoned, outdated and now likely malicious qb64 dot net website - don’t go there] in which Steve talks about REDIM  _PRESERVE and the managment of memory

UDT with fixed string vs variable string  https://www.qb64.org/forum/index.php?topic=1753.msg110020#msg110020

another issue about _PRESERVE https://www.qb64.org/forum/index.php?topic=398.msg2766#msg2766

  [ You are not allowed to view this attachment ]  

copying array FOR vs _MEM  https://www.qb64.org/forum/index.php?topic=322.msg2156#msg2156

here linked list
https://www.qb64.org/forum/index.php?topic=982.msg101768#msg101768

here the sort routines
https://www.qb64.org/forum/index.php?topic=530.msg3830#msg3830

here loading and saving array to file using _MEM
https://www.qb64.org/forum/index.php?topic=387.msg2632#msg2632

Thanks to read
Programming isn't difficult, only it's  consuming time and coffee

Offline STxAxTIC

  • Library Staff
  • Forum Resident
  • Posts: 1091
  • he lives
    • View Profile
Re: REDIM _PRESERVE bug
« Reply #14 on: March 29, 2020, 08:21:54 am »
here linked list
https://www.qb64.org/forum/index.php?----------------

Nah. That was well-argued to not be the real thing.

My examples are rather convoluted but the simplest one must be qXed: https://www.qb64.org/forum/index.php?topic=1642.msg108603#msg108603

The whole nugget is contained in the Cell UDT. If you see why I need this, and how it is generalized, you're all set. (All it does is store single characters. Simplest example I have.)

Code: QB64: [Select]
  1. TYPE Cell
  2.     Identity AS LONG
  3.     Pointer AS LONG
  4.     Lagger AS LONG
  5.     Content AS STRING * 1
« Last Edit: March 29, 2020, 08:40:36 am by STxAxTIC »
You're not done when it works, you're done when it's right.