Author Topic: My First Attempt with MEM  (Read 4773 times)

0 Members and 1 Guest are viewing this topic.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
My First Attempt with MEM
« on: September 06, 2019, 05:26:39 pm »
I see a future need to copy a SINGLE array to another, so I tried Steve's lesson on MEM, it worked!

I tried to extend it to strings?, nope, fixed strings? nope, unless I am doing something wrong?

Code: QB64: [Select]
  1. _TITLE "Mem test for array copy" 'B+ 2019-09-06
  2. DIM a(1 TO 20), a1(1 TO 20) AS STRING * 100 'cant do variable length strings , apparently not fixed strings either
  3. REDIM bCopy(0), b1Copy(0) AS STRING * 100
  4.  
  5. FOR i = 1 TO 20
  6.     a(i) = INT(10000 * RND) / 100
  7.     a1(i) = STR$(a(i))
  8.  
  9. sngArrCopy a(), bCopy()
  10. 'FixStr100ArrCopy a1(), b1Copy()
  11.  
  12.  
  13. FOR i = 1 TO 20
  14.     PRINT i, bCopy(i) ', _TRIM$(b1Copy(i))
  15.  
  16. SUB sngArrCopy (A!(), copyB!())
  17.     REDIM copyB!(LBOUND(a!) TO UBOUND(a!)) 'container for _memget is ready
  18.     DIM m AS _MEM
  19.     m = _MEM(A!())
  20.     _MEMGET m, m.OFFSET, copyB!()
  21.  
  22. 'this wont work C++ doesn't like it
  23. 'SUB FixStr100ArrCopy (A() AS STRING * 100, copyB() AS STRING * 100)
  24. '    REDIM copyB(LBOUND(a) TO UBOUND(a)) AS STRING * 100 'container for _memget is ready
  25. '    DIM m AS _MEM
  26. '    m = _MEM(A())
  27. '    _MEMGET m, m.OFFSET, copyB()
  28. 'END SUB
  29.  
  30.  

Well at least I can copy a Single Array.

Offline Petr

  • Forum Resident
  • Posts: 1720
  • The best code is the DNA of the hops.
    • View Profile
Re: My First Attempt with MEM
« Reply #1 on: September 06, 2019, 06:00:44 pm »
Hi BPlus. I create it so:

Code: QB64: [Select]
  1. _TITLE "Mem test for array copy" 'B+ 2019-09-06
  2. DIM a(1 TO 20), a1(1 TO 20) AS STRING * 100 'cant do variable length strings , apparently not fixed strings either
  3. REDIM bCopy(0), b1Copy(0) AS STRING * 100
  4.  
  5. FOR i = 1 TO 20
  6.     a(i) = INT(10000 * RND) / 100
  7.     a1(i) = STR$(a(i))
  8.  
  9. sngArrCopy a(), bCopy()
  10. FixStr100ArrCopy a1(), b1Copy()
  11.  
  12.  
  13. FOR i = 1 TO 20
  14.     PRINT i; bCopy(i); _TRIM$(b1Copy(i))
  15.     SLEEP
  16.  
  17. SUB sngArrCopy (A!(), copyB!())
  18.     REDIM copyB!(LBOUND(a!) TO UBOUND(a!)) 'container for _memget is ready
  19.     DIM m AS _MEM
  20.     m = _MEM(A!())
  21.     _MEMGET m, m.OFFSET, copyB!()
  22.  
  23. 'this wont work C++ doesn't like it
  24. SUB FixStr100ArrCopy (A() AS STRING * 100, copyB() AS STRING * 100)
  25.     REDIM copyB(LBOUND(a) TO UBOUND(a)) AS STRING * 100 'container for _memget is ready
  26.     DIM n AS _MEM
  27.     n = _MEM(A())
  28.     DIM ch AS STRING
  29.     FOR i = 1 TO 20
  30.         ch$ = _MEMGET(n, n.OFFSET + (i - 1) * 99, STRING * 100)
  31.         copyB(i) = ch$
  32.     NEXT
  33.  
  34.  
  35.  
  36.  

Offline Petr

  • Forum Resident
  • Posts: 1720
  • The best code is the DNA of the hops.
    • View Profile
Re: My First Attempt with MEM
« Reply #2 on: September 06, 2019, 06:04:18 pm »
It works, but I still think the FOR NEXT loop is going to take speed down. I'm sure Steve will do it at least 80 times faster :)

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: My First Attempt with MEM
« Reply #3 on: September 06, 2019, 06:51:19 pm »
Hi Petr,

Yeah, I was hoping to get it all in one bite, like scooping up a Binary File.

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: My First Attempt with MEM
« Reply #4 on: September 06, 2019, 08:03:34 pm »
I tried to extend it to strings?, nope, fixed strings? nope, unless I am doing something wrong?

Variable length strings won't work with _MEM, as their position in memory is fluid and can move at any moment.  If you're directly accessing a pointer to a variable length string, you need to be aware that you're playing Russian Roulette with your program.  That memory can move between the time you get the _OFFSET for it, and the very next line when you try and use that _OFFSET to change/view it... 

Fixed length strings should work just fine with _MEM, and it seems you've probably discovered a bug in the command.  It'll need further testing and debugging, but unless Luke or Felippe knows some underlying reason I don't, we should be able to do what you were trying to do with your code. 

The way I'd normally do what you're trying to do is like so (and is probably why I've never encountered the glitch myself before):
Code: QB64: [Select]
  1. _TITLE "Mem test for array copy" 'B+ 2019-09-06
  2. DIM a(1 TO 20), a1(1 TO 20) AS STRING * 100 'cant do variable length strings , apparently not fixed strings either
  3. REDIM bCopy(0), b1Copy(0) AS STRING * 100
  4.  
  5. FOR i = 1 TO 20
  6.     a(i) = INT(10000 * RND) / 100
  7.     a1(i) = STR$(a(i))
  8.  
  9. sngArrCopy a(), bCopy()
  10. FixStr100ArrCopy a1(), b1Copy()
  11.  
  12.  
  13. FOR i = 1 TO 20
  14.     PRINT i, bCopy(i), _TRIM$(b1Copy(i))
  15.  
  16. SUB sngArrCopy (A!(), copyB!())
  17.     REDIM copyB!(LBOUND(a!) TO UBOUND(a!)) 'container for _memget is ready
  18.     DIM m AS _MEM
  19.     m = _MEM(A!())
  20.     _MEMGET m, m.OFFSET, copyB!()
  21.     _MEMFREE m
  22.  
  23. SUB FixStr100ArrCopy (A() AS STRING * 100, copyB() AS STRING * 100)
  24.     REDIM copyB(LBOUND(a) TO UBOUND(a)) AS STRING * 100 'container for _memget is ready
  25.     DIM m AS _MEM, m1 AS _MEM
  26.     m = _MEM(A()): m1 = _MEM(copyB())
  27.     _MEMCOPY m, m.OFFSET, m.SIZE TO m1, m1.OFFSET
  28.     _MEMFREE m
  29.     _MEMFREE m1

Just don't forget to _MEMFREE when you're finished, or else you're introducing a memory leak in your program which will accumulate and eventually lead to crashing after enough calls/repetitions. 
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: My First Attempt with MEM
« Reply #5 on: September 06, 2019, 08:47:51 pm »
Thanks Steve, I like breaking new ground.

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: My First Attempt with MEM
« Reply #6 on: September 06, 2019, 08:56:35 pm »
Thanks Steve, I like breaking new ground.

Just curious, but can’t  you also just do this, in this instance:

B() = A()
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: My First Attempt with MEM
« Reply #7 on: September 06, 2019, 09:00:08 pm »
Ha! for some reason I thought I couldn't I thought I tried a long long time ago with a Life variation...

hmm well this easy enough to check!

Nope!
Code: QB64: [Select]
  1. DIM a(1 TO 20), b(1 TO 20)
  2.  
  3. FOR i = 1 TO 20
  4.     a(i) = INT(10000 * RND) / 100
  5.  
  6. b() = a()
  7. FOR i = 1 TO 20
  8.     PRINT i, b(i)
  9.  

Neither with Dynamic arrays:
Code: QB64: [Select]
  1. REDIM a(1 TO 20), b(1 TO 20)
  2.  
  3. FOR i = 1 TO 20
  4.     a(i) = INT(10000 * RND) / 100
  5.  
  6. b() = a()
  7. FOR i = 1 TO 20
  8.     PRINT i, a(i), b(i)
  9.  
  10.  

It is curious that the first element does copy ??
« Last Edit: September 06, 2019, 09:05:32 pm by bplus »

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: My First Attempt with MEM
« Reply #8 on: September 06, 2019, 09:14:51 pm »
More notes from Steve's extended lesson (IRC) on _MEM stuff,

Along with _MEMCOPY, there is also _MEMFILL added to end of main:

Code: QB64: [Select]
  1. _TITLE "Mem test for array copy" 'B+ 2019-09-06
  2.  
  3. ' Don't forget _Memfree
  4.  
  5. DIM a(1 TO 20), a1(1 TO 20) AS STRING * 100 'cant do variable length strings , apparently not fixed strings either
  6. REDIM bCopy(0), b1Copy(0) AS STRING * 100
  7.  
  8. FOR i = 1 TO 20
  9.     a(i) = INT(10000 * RND) / 100
  10.     a1(i) = STR$(a(i))
  11.  
  12. sngArrCopy a(), bCopy()
  13. FixStr100ArrCopy a1(), b1Copy()
  14. FOR i = 1 TO 20
  15.     PRINT i, bCopy(i), _TRIM$(b1Copy(i))
  16.  
  17. 'example Steve's for MemFill
  18. DIM b(1 TO 10) AS INTEGER, m AS _MEM
  19. m = _MEM(b())
  20. _MEMFILL m, m.OFFSET, m.SIZE, &HFFFE AS INTEGER '<--- Presto!  It's now full with 10 values of 65535 (&HFFFF)
  21. FOR i = 1 TO 10
  22.     PRINT b(i)
  23.  
  24.  
  25. SUB sngArrCopy (A!(), copyB!())
  26.     REDIM copyB!(LBOUND(a!) TO UBOUND(a!)) 'container for _memget is ready
  27.     DIM m AS _MEM
  28.     m = _MEM(A!())
  29.     _MEMGET m, m.OFFSET, copyB!()
  30.     _MEMFREE m '<<<<<<<<<<<<<<<<<<<<<<<<<< like freeimage very important
  31.  
  32. 'this wont work C++ doesn't like it
  33. 'SUB FixStr100ArrCopy (A() AS STRING * 100, copyB() AS STRING * 100)
  34. '    REDIM copyB(LBOUND(a) TO UBOUND(a)) AS STRING * 100 'container for _memget is ready
  35. '    DIM m AS _MEM
  36. '    m = _MEM(A())
  37. '    _MEMGET m, m.OFFSET, copyB()
  38. 'END SUB
  39.  
  40. 'Steve's fix for strings
  41. SUB FixStr100ArrCopy (A() AS STRING * 100, copyB() AS STRING * 100)
  42.     REDIM copyB(LBOUND(a) TO UBOUND(a)) AS STRING * 100 'container for _memget is ready
  43.     DIM m AS _MEM, m1 AS _MEM
  44.     m = _MEM(A()): m1 = _MEM(copyB())
  45.     _MEMCOPY m, m.OFFSET, m.SIZE TO m1, m1.OFFSET
  46.     _MEMFREE m
  47.     _MEMFREE m1
  48.  
  49.  
  50.  

Offline Petr

  • Forum Resident
  • Posts: 1720
  • The best code is the DNA of the hops.
    • View Profile
Re: My First Attempt with MEM
« Reply #9 on: September 07, 2019, 04:27:44 am »
Also, thank you Steve for showing me how to do it better.

Offline Ashish

  • Forum Resident
  • Posts: 630
  • Never Give Up!
    • View Profile
Re: My First Attempt with MEM
« Reply #10 on: September 07, 2019, 10:00:49 am »
Yeah! Thanks Steve for this. I had learned about _MEM from his (Steve) and Walter codes.
if (Me.success) {Me.improve()} else {Me.tryAgain()}


My Projects - https://github.com/AshishKingdom?tab=repositories
OpenGL tutorials - https://ashishkingdom.github.io/OpenGL-Tutorials