Reset/empty string ARRAY$ ?


Author Message
electricat

Senior Member

Joined: 30/11/2020
Location: Lithuania
Posts: 279
Posted: 06:29pm 10 Mar 2025      

So, I created var inside SUB

LOCAL dirct$(255) length 16

Time to time I need clear/reset/empty values in array.

I could do it cycling --> dirct$(n) = ""

But it looks to me, it might be some simple/faster way??

I wanted to use ERASE and re-declare, but this seems ERASE will not to work inside SUB

Any advice please...

twofingers
Guru

Joined: 02/06/2014
Location: Germany
Posts: 1501
Posted: 06:36pm 10 Mar 2025      

I would also like a solution for that.
Redim a string array with erase works with Erase/Dim within subs.*

Regards
Michael


* See FM02000!
Edited 2025-03-11 04:40 by twofingers

matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 9957
Posted: 06:49pm 10 Mar 2025      

Sub test
 Const slen=16
 Local dirct$(255) length slen
 dirct$(255)="1234567890abcdef"
 dirct$(0)="ABCDEFGHIJKLMNOP"
 Print dirct$(0),dirct$(255)
 Local integer a%=Peek(varaddr dirct$())
 Memory set byte a%,0,(Bound(dirct$(),1)+1)*(slen+1)
 Print dirct$(0),dirct$(255)
End Sub

javavi

Guru

Joined: 01/10/2023
Location: Ukraine
Posts: 432
Posted: 07:07pm 10 Mar 2025      

@matherp

Is there a clever way to reserve a byte array in the RAM variable area (not in the heap) and have byte-by-byte access to it using the PEEK POKE commands?
Let's say two arrays of 200-500 bytes each.
Edited 2025-03-11 05:12 by javavi

electricat

Senior Member

Joined: 30/11/2020
Location: Lithuania
Posts: 279
Posted: 07:10pm 10 Mar 2025      

@Peter,

For me looks like memset(myArray, 0, sizeof(myArray))  but in MMBasic    ?

Recently I was interested in varaddr etc. manipulations but I failed to find in documentation more detailed info how vars are stored. Played a bit peeking poking memory, and found it interesting  

Thank you boys.
Will play.
Edited 2025-03-11 05:11 by electricat

matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 9957
Posted: 07:17pm 10 Mar 2025      

  Quote  Is there a clever way to reserve a byte array in the RAM variable area (not in the heap) and have byte-by-byte access to it using the PEEK POKE commands?
Let's say two arrays of 200-500 bytes each.


No: it's a hash table
Edited 2025-03-11 05:17 by matherp

twofingers
Guru

Joined: 02/06/2014
Location: Germany
Posts: 1501
Posted: 07:27pm 10 Mar 2025      

  matherp said  
Sub test
 Const slen=16
 Local dirct$(255) length slen
 dirct$(255)="1234567890abcdef"
 dirct$(0)="ABCDEFGHIJKLMNOP"
 Print dirct$(0),dirct$(255)
 Local integer a%=Peek(varaddr dirct$())
 Memory set byte a%,0,(Bound(dirct$(),1)+1)*(slen+1)

 Print dirct$(0),dirct$(255)
End Sub


Thanks Peter! I will play with it!
Regards
Michael

CaptainBoing

Guru

Joined: 07/09/2016
Location: United Kingdom
Posts: 2133
Posted: 07:33pm 10 Mar 2025      

MicroMite: Unless this is peculiar to SUB, this must be a change (possibly to do with hashed variables). My code for SPLIT() routine ERASEs and DIMs an array in a FUNCTION()

h

CaptainBoing

Guru

Joined: 07/09/2016
Location: United Kingdom
Posts: 2133
Posted: 07:39pm 10 Mar 2025      

  electricat said  
Recently I was interested in varaddr etc. manipulations but I failed to find in documentation more detailed info how vars are stored.


My work was aimed at MicroMites and so I don't think it will be useful to you. I did a lot of work on this to come up with my UBOUND() function

for interest's sake...



and some code that helped

option base 0

dim a$(9)
dim integer fred
const bim=99

fred=1

?
for n=0 to 511 step 16
b$=""
? Hex$(n,4);"  ";
for m=0 to 15
q=PEEK(VARTBL, n+m)
? hex$(q,2);" ";
if q<32 or q>126 then q=46
b$=b$+chr$(q)
next
?"  ";b$
fred=fred+1:If fred>4 then fred=1:print
next

erase a$

fred=1

?
for n=0 to 511 step 16
b$=""
? Hex$(n,4);"  ";
for m=0 to 15
q=PEEK(VARTBL, n+m)
? hex$(q,2);" ";
if q<32 or q>126 then q=46
b$=b$+chr$(q)
next
?"  ";b$
fred=fred+1:If fred>4 then fred=1:print
next

dim bb$(5), a$(2)

fred=1

?
for n=0 to 511 step 16
b$=""
? Hex$(n,4);"  ";
for m=0 to 15
q=PEEK(VARTBL, n+m)
? hex$(q,2);" ";
if q<32 or q>126 then q=46
b$=b$+chr$(q)
next
?"  ";b$
fred=fred+1:If fred>4 then fred=1:print
next


I have discussed this on and off here - just do a search for UBOUND

h
Edited 2025-03-11 05:42 by CaptainBoing

electricat

Senior Member

Joined: 30/11/2020
Location: Lithuania
Posts: 279
Posted: 08:01pm 10 Mar 2025      

@CaptainBoing

I highly like this   Brings back memories of zx spectrum. Games hacking and such.
Devs` have no time to describe  things like this. But I can understand  

javavi

Guru

Joined: 01/10/2023
Location: Ukraine
Posts: 432
Posted: 08:11pm 10 Mar 2025      

@CaptainBoing @matherp
How wasteful is the memory usage in this hash table for a microcontroller with limited memory resources?

electricat

Senior Member

Joined: 30/11/2020
Location: Lithuania
Posts: 279
Posted: 08:13pm 10 Mar 2025      

  javavi said  @matherp

Is there a clever way to reserve a byte array in the RAM variable area (not in the heap) and have byte-by-byte access to it using the PEEK POKE commands?
Let's say two arrays of 200-500 bytes each.


Might be doubtfull idea, but SPRITE READ, BLIT READ creates kind of 'protected memory'    
You only need to find address where it is stored (search pattern) and use it in a way you want   But I do not know sprites or blit memory management works. Peter knows  

As I said - doubtfull idea. But we used to do all kind of nonsenses with ZX spectrum :D

electricat

Senior Member

Joined: 30/11/2020
Location: Lithuania
Posts: 279
Posted: 08:34pm 10 Mar 2025      

wwwohaaa
Memory set byte a%,0,(Bound(dirct$(),1)+1)*17
timer diff ->> 0.072
for a=0 to 255
dirct$(a)=""
next a
timer diff ->> 3.86 !!

means 53x faster     
Edited 2025-03-11 06:35 by electricat

Bleep
Guru

Joined: 09/01/2022
Location: United Kingdom
Posts: 568
Posted: 09:06pm 10 Mar 2025      

I believe it'll be 17 times that for your For Next loop, currently you are only clearing 256 bytes, Peters is clearing 256*17 bytes?
Presumably the string may be gone, but the data may still be there in the unclear memory.
Regards Kevin
Edited 2025-03-11 07:11 by Bleep

CaptainBoing

Guru

Joined: 07/09/2016
Location: United Kingdom
Posts: 2133
Posted: 11:08am 11 Mar 2025      

  javavi said  @CaptainBoing @matherp
How wasteful is the memory usage in this hash table for a microcontroller with limited memory resources?


To be clear about this - my point of reference for all this is Micromite Mk2 (PIC32MX170-based). The graphic above shows the VARTBL memory layout for that 'mite, which does not use hashed variables and is unlikely ever to do so - being considered "finished" and updates to the firmware are for serious bugs only. Each variable there takes 64 bytes in the table - I can account for around 50 of them so not that bad at all and a small price to pay to keep things a nice "CPU-sized" number.

The "worst waste" is using undimensioned strings - they are all 255 bytes long - even
A$="Hello World!"

and the syntactically accepted LENGTH is ignored for single variables. I think this extends to all 'mite flavours - anyone?

You can make things a bit better if you are REALLY low on RAM by making sure all your string variables are part of an array and then using LENGTH, but it doesn't make for easy reading and there is a tiny speed penalty. Using a CONST to identify specific members of the array can help, but it's an awful faf and arguably just moving the problem to flash storage from RAM (but this does save 500 bytes):


'very convuluted but you get the idea
Const Greeting=1
Const Goodbye=2

Option Base 1

Dim m$(2) =("wotcha","tata") Length 10

Print m$(Greeting)

Print m$(Goodbye)


In all honesty, I have yet to be seriously hampered by this and it really doesn't stop me sleeping. Birds. Birds stop me sleeping.

h
Edited 2025-03-11 21:26 by CaptainBoing

twofingers
Guru

Joined: 02/06/2014
Location: Germany
Posts: 1501
Posted: 11:54am 11 Mar 2025      

  CaptainBoing said  ... and the syntactically accepted LENGTH is ignored for single variables. I think this extends to all 'mite flavours - anyone?...


I think this is only correct for PicoMites for lengths of 8 characters or more.

https://www.thebackshed.com/forum/ViewTopic.php?FID=16&TID=17750
Regards
Michael

Volhout
Guru

Joined: 05/03/2018
Location: Netherlands
Posts: 4809
Posted: 12:06pm 11 Mar 2025      

Integers and floats are 64 bits (8 bytes).
For integers and floats a reserved memory block is used (28kbyte) that is not part of the dynamic heap.
A string up to 8 characters fits inside 64bits, and could become part of this reserved memory block (so it is not part of the dynamic heap).

That is pefectly in line with Captains vatrtable analysis above (March 10 post).

Volhout
Edited 2025-03-11 22:08 by Volhout

thwill

Guru

Joined: 16/09/2019
Location: United Kingdom
Posts: 4223
Posted: 12:08pm 11 Mar 2025      

  twofingers said  
  CaptainBoing said  ... and the syntactically accepted LENGTH is ignored for single variables. I think this extends to all 'mite flavours - anyone?...


I think this is only correct for PicoMites for lengths of 8 characters or more.


- Each MMBasic variable takes ~64 bytes in the variable table.
- Most of this is used by the name, type, dimensions, etc.
- 8 of these bytes are used for storage, enough for a 64-bit FLOAT, INTEGER, a very short string (7/8 chars? - but not on Micromites or currently MMB4L) or a pointer into the heap for a larger string or array.
- Space on the heap is always allocated in 256 byte pages ... hence a larger string always taking 256 bytes and the minimum allocation for an array being 256 bytes.

Best wishes,

Tom

thwill

Guru

Joined: 16/09/2019
Location: United Kingdom
Posts: 4223
Posted: 12:10pm 11 Mar 2025      

  Volhout said  A string up to 8 characters fits inside 64bits, ...


On reflection I suspect it is one byte containing the current length and *7* characters.

Tom

matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 9957
Posted: 12:14pm 11 Mar 2025      

  Quote  On reflection I suspect it is one byte containing the current length and *7* characters.


Doesn't work like that. The vartbl entry still contains a pointer so nothing else needs changing. For short strings it points to the second element of the dimension array which is repurposed to contain the string