Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.
|
Forum Index : Microcontroller and PC projects : Dynamic ReDim arrays
Author | Message | ||||
Malibu Senior Member Joined: 07/07/2018 Location: AustraliaPosts: 228 |
Working with a few arrays at the moment, and I'm dynamically declaring them depnding on how many elements I need at the time. It's for a list of users that the 'number' is only known at run time. Easy to create an array based on the amount of users on first load, but if I want to add another user (or more), I can't because the array size won't allow it. So, falling back to VB6, I wrote a ReDim function that will resize the array with an extra element. Ideally, I want to call the sub with ReDim(preserve|destroy, "NameOfArray", newsize) so I can change any of the arrays and either preserve or destroy them. Here's part of the code : OPTION EXPLICIT OPTION DEFAULT NONE option base 1 dim integer True=1, False=0, Preserve=True, Destroy = False ' '****---- these 2 lines fails **** dim string ArrayName = "TestArr" dim string ArrayName(2) length 20 'create the initial array ' '****---- this line works **** 'dim string TestArr(2) length 20 'create the initial array ' dim integer i = 1, j = 0 'gp variables ? "Initialised array elements :" for j = 1 to 2 'loop here TestArr(j) = "Array Element " + str$(j) 'and write some initial data to the array ? "Element " + str$(j) + " = " + TestArr(j) 'debug print next j << and the code goes on after here>> Works great if I declare the ArrayName directly in code, but come unstuck when I try to declare the ArrayName as a variable. I get this error message [10] Dim string ArrayName(2) length 20 'create the initial array Error : Array dimensions As I have 5 arrays that all need to be ReDimmed, I'd prefer to be able to write a ReDim sub once, that can be called per array when needed. I'd apreciate anyone's thoughts or ideas on how to get around my error, or even if this is an impossible idea. John |
||||
matherp Guru Joined: 11/12/2012 Location: United KingdomPosts: 9110 |
You should be able to do what you want using the EXECUTE command. Construct the DIM as a string which will allow you to embed the array name as a variable and then use execute to action it |
||||
Malibu Senior Member Joined: 07/07/2018 Location: AustraliaPosts: 228 |
Thanks Peter, that's great and at least partially helped my code in that I can create arrays by indirect reference : dim string ArrName = "TestArr" dim integer ArrSize = 8 dim string ArrCreate = "dim string " + ArrName + "(" + str$(arrsize) + ") length 20" ' This successfully creates an array <ArrName> of <ArrSize> number of elements by indirect reference execute ArrCreate which gives me : 'This successfuly writes and reads the array using direct reference to the array for i = 1 to bound(testarr()) testarr(i) = "Array Element No. " + str$(i) 'write to the array ? testarr(i) 'read back and print what's in the array next i but when I try to indirect reference write to the array with this, I get errors : for i = 1 to arrsize dim string ArrWrite = ArrName + "(" + str$(i) + ") = " + str$(i) ? str$(i) 'prints - 1 ? arrwrite 'prints - TestArr(1) = 1 execute arrwrite 'results in: - [(line) 26] Execute arrwrite - Error : Expected a string next i with variations on a theme, I can get 'expected a string', 'blahblahblah not declared', 'yaddayaddayadda already declared' errors, plus a few more that I can't recall right now... (What can I say, I've been 2 days on this...) I'll keep plodding on to understand what's going on for a solution, but right now it's messing with my sanity. Thought I'd put the problem out and see if there's an 'easy' fix that I may have missed... prior to my 12lb sledgy making chips out of the Pico! Love the EXECUTE command though, what a delicate way to do things John |
||||
phil99 Guru Joined: 11/02/2018 Location: AustraliaPosts: 2135 |
My experience is Execute does not work inside a Do Loop or For Next, in addition to the limitations documented in the manual. |
||||
TassyJim Guru Joined: 07/08/2011 Location: AustraliaPosts: 6097 |
' DIM STRING ArrName = "TestArr" DIM INTEGER ArrSize = 8 DIM STRING ArrCreate = "dim string " + ArrName + "(" + STR$(arrsize) + ") length 20" DIM STRING Fred DIM STRING arrWRite, arrRead ' This successfully creates an array <ArrName> of <ArrSize> number of elements by indirect reference EXECUTE ArrCreate 'which gives me : 'This successfuly writes and reads the array using direct reference to the array FOR i = 1 TO BOUND(testarr()) testarr(i) = "Array Element No. " + STR$(i) 'write to the array ? testarr(i) 'read back and print what's in the array NEXT i 'but when I try to indirect reference write to the array with this, I get errors : FOR i = 1 TO arrsize ArrWrite = ArrName + "(" + STR$(i) + ") = " + STR$(i) arrread = "Fred = "+ ArrName + "(" + STR$(i) + ")" ? STR$(i) 'prints - 1 ? arrwrite 'prints - TestArr(1) = 1 EXECUTE arrread 'results in: - [(line) 26] Execute arrwrite ' - Error : Expected a string PRINT fred NEXT i VK7JH MMedit MMBasic Help |
||||
Mixtel90 Guru Joined: 05/10/2019 Location: United KingdomPosts: 6780 |
I hope you aren't trying to redim arrays while preserving the data in them. I'm not sure if you'll get that to work. Much, much easier to write to a random access file (or several of them) on A: and just keep a track on where you've put things using a single oversized array. A: is fast. AFAIK arrays and strings need contiguous RAM in the variables area. As soon as you create a new variable after creating an array using DIM or creating a string there's a chance that the array can't be extended. I may very well be wrong, but that would be logical. Execute is getting you round creating arrays nicely, but I suspect that's all. Mick Zilog Inside! nascom.info for Nascom & Gemini Preliminary MMBasic docs & my PCB designs |
||||
JohnS Guru Joined: 18/11/2011 Location: United KingdomPosts: 3800 |
Your ArrWrite needs more quotes - because you've made TestArr a string array but are trying to write a numeric (the loop count) to each element You want something like: ArrWrite = ArrName + "(" + STR$(i) + ") = " + CHR$(34) + STR$(i) + CHR$(34) John Edited 2024-08-13 23:43 by JohnS |
||||
TassyJim Guru Joined: 07/08/2011 Location: AustraliaPosts: 6097 |
That line does work without the added quotes. Depending on the actual use, you may be correct and quotes needed. Using EXECUTE you have two conditions to satisfy - making the command line a string and then making it obey all the rules when it's executed. STR$(i) is a string so the first part is satisfied and EXECUTE seems to be happy without the quotes during the second part - executing. Jim VK7JH MMedit MMBasic Help |
||||
Malibu Senior Member Joined: 07/07/2018 Location: AustraliaPosts: 228 |
Brilliant! Many thanks to everyone... Not sure I coulda figured it out by flying solo... John, spot on with writing data using your suggestion. I didn't even twig that I needed the Chr$(34) for the missing " chars, but made sense when I coded them in... ArrWrite = ArrName + "(" + STR$(i) + ") = " + CHR$(34) + STR$(i) + CHR$(34) Jim, your suggestion also made sense once I coded it in, which worked perfectly. One of those "How was I so dumb...??" moments for me! arrread = "Fred = "+ ArrName + "(" + STR$(i) + ")" That's probably right Phil, but it's my first Execute command... Wasn't really sure on how to do things, but yeah, calling it in a loop gave an "already declared" error, and I scrapped that idea. Yeah Mick, that's exactly what I'm trying to do. My idea to get around the limitations you mentioned is to create a temporary array, copy all the existing data over, erase the source array, re-create it to the new size and copy all the data back again. It's an idea; maybe futile, but it might do exacly what I need. At the very least, it's been a good learning tool Thanks to everyone's input and assistance... here's the code I ended up with : dim string ArrData = "" dim integer i = 0 dim string ArrName = "ThisArr" '**** change for another array name dim integer ArrSize = 9 '**** change for another array size dim string ArrCreate = "dim string " + ArrName + "(" + str$(ArrSize) + ") length 20" dim string ArrWrite = ArrName + "(" + STR$(i) + ") = " + CHR$(34) + STR$(i) + CHR$(34) dim string ArrRead = ArrName + "("+ STR$(i) + ")" execute ArrCreate WriteToArr ReadFromArr end sub WriteToArr ? ? "Writing Data to '" + ArrName + "' (" + str$(ArrSize) + " elements)" for i = 1 to ArrSize ArrData = "Array Element No. " + STR$(i) ArrWrite = ArrName + "(" + STR$(i) + ") = " + CHR$(34) + ArrData + CHR$(34) ? " Written data - " + ArrData execute ArrWrite next i end sub sub ReadFromArr ? ? "Reading Data from '" + ArrName + "' (" + str$(ArrSize) + " elements)" for i = 1 to ArrSize ArrRead = "ArrData = " + ArrName + "(" + str$(i) + ")" execute ArrRead ? " Read data - " + ArrData next i end sub John |
||||
Malibu Senior Member Joined: 07/07/2018 Location: AustraliaPosts: 228 |
I just twigged that I only need to declare ArrRead and ArrWrite simply as strings dim string ArrWrite dim string ArrRead Even better! John |
||||
Mixtel90 Guru Joined: 05/10/2019 Location: United KingdomPosts: 6780 |
Personally I think I'd still go for the file approach. When your file is stored on flash and you aren't having to fight through Windows or DOS it's not the same. :) The problem with the array system is that you are going to run out of RAM in the variables area pretty quickly if you re-DIM string arrays. You'll need space for the original array + the temporary array + the new array. Numeric arrays are much more predictable, of course. Can anyone clarify this? I think there's a minimum working value for LENGTH irrespective of what you set it to. So, for example, LENGTH 2 uses a lot more than 2 bytes per string element of the array. I can't find it in the manual. I have a feeling that it might be 16 bytes. Mick Zilog Inside! nascom.info for Nascom & Gemini Preliminary MMBasic docs & my PCB designs |
||||
Malibu Senior Member Joined: 07/07/2018 Location: AustraliaPosts: 228 |
Yep, one of my questions to answer as well. I haven't discounted the 'save-to-file' method as yet, this is just my first path of experiments. I need to access 5 or 6 db-arrays, simultaniuosly at a possibly fast rate, so my first thoughts are to access the already created (and active) arrays, rather than open/close and/or holding files open. I only need to ReDim the arrays very occasionally. Either way will do the trick, it's just figuring out what's the best trick to use. A good suggestion though, one that I'll likely trial down the track As to your minimum byte size for LENGTH, I've no idea - another experiment, I guess Edit: Actually, it's the 'original array' + 'temp array' - 'original array' + 'new array' = only 2 arrays ever exist. Of course, X 5 = a mere, 10 arrays! No problems! Edited 2024-08-14 17:24 by Malibu John |
||||
phil99 Guru Joined: 11/02/2018 Location: AustraliaPosts: 2135 |
A search for "length" and "matherp" gave this:- |
||||
Malibu Senior Member Joined: 07/07/2018 Location: AustraliaPosts: 228 |
Thanks to everyone for the help here... It's been a very interesting code session for me. I'm pretty sure with the over-bloated code that I ended up with (for a really small application), Micro$oft could offer me a job - I could show 'em a few pointless coding tips Anyways, final result is attached - there's still a few lingering things that might need touchups (error traps, etc) but it seems to do what I wanted. I'm fairly certain I've also got a little memory bleed somewhere in the ReDim/preserve side of it, but I would need to do some more testing to find out for sure. My final thoughts? Too complicated, too code intensive and not advantageous enough to be a serious contender for anything serious. See what you think ReDim Ver 3.zip John |
||||
Print this page |