Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 06:56 02 Aug 2025 Privacy Policy
Jump to

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 : String variables and the length qualifyer

Author Message
panky

Guru

Joined: 02/10/2012
Location: Australia
Posts: 1114
Posted: 04:08am 26 Jan 2019
Copy link to clipboard 
Print this post

I understand that the LENGTH qualifyier that can be used with string arrays does nothing on a normal string.

In most of my programs I use dozens of string variables and most are very short (ie. less than 10 to 30 characters). A recent example is where I have 34 string variables - none of which are longer than 16 characters. With all strings normally being 256 characters in size, I am using 256 x 34 = 8705 bytes whereas if the length qualifyer could be used, I would only need 16 x 34 = 544 bytes! A very significant saving in large programs.

So, my question is "would it be possible to have the length qualifyer also apply to normal string variables"?

Perhaps one for Geoff or Peter?

panky.

... almost all of the Maximites, the MicromMites, the MM Extremes, the ArmMites, the PicoMite and loving it!
 
TassyJim

Guru

Joined: 07/08/2011
Location: Australia
Posts: 6283
Posted: 04:51am 26 Jan 2019
Copy link to clipboard 
Print this post

You could store them in an array.

Jim

VK7JH
MMedit
 
Geoffg

Guru

Joined: 06/06/2011
Location: Australia
Posts: 3292
Posted: 06:02am 26 Jan 2019
Copy link to clipboard 
Print this post

This is to do with the memory allocation algorithm. When you declare a string MMBasic will ask the memory management system for some RAM to store the string. This is allocated in chunks of 256 bytes which, in part, is why strings are limited to 255 bytes (the extra byte is used to record the string length). Even if you ask for 16 bytes you will still get 256 bytes.

Memory allocation is a trade off between the chunk size and the efficiency of the algorithm. Large chunk sizes are more efficient to keep track of compared to small chunks. For the Micromite 256 byte chunks seemed about right.

The other aspect is that Micromites have plenty of RAM anyway. For example, you have 32 string variables which take 8K but that is small compared to the 50K of free RAM that the humble 28-pin Micromite has (the MM+ has double this). Reducing the size of the memory allocated to each string would have little practical impact.

Arrays of strings are a different matter. They can rapidly consume all the free RAM so MMBasic will ask for the array size times the LENGTH qualifier. The allocated memory will still have a minimum of 256 bytes and will be rounded up to make an integer number of 256 byte chunks but within that allocation many string elements can be stored.

I hope that this makes sense.

Geoff
Geoff Graham - http://geoffg.net
 
TassyJim

Guru

Joined: 07/08/2011
Location: Australia
Posts: 6283
Posted: 06:02am 26 Jan 2019
Copy link to clipboard 
Print this post

To add:
A variable name takes up 32 bytes so by using an array you save those 32 bytes for each variable as well as making use of the LENGTH parameter.

Jim

VK7JH
MMedit
 
Turbo46

Guru

Joined: 24/12/2017
Location: Australia
Posts: 1642
Posted: 06:12am 26 Jan 2019
Copy link to clipboard 
Print this post

I agree Panky,

I was surprised to learn only recently that the LENGTH qualifier didn't apply to normal strings. The MMBasic manual I have printed out says that it can be used for normal strings but I know it has been changed in later versions to say that it won't save any memory.

While you could use an array, that doesn't allow for intuitive names for the individual strings and could make the code harder to read.

Bill

Edit: Sorry didn't see the last two posts.Edited by Turbo46 2019-01-27
Keep safe. Live long and prosper.
 
panky

Guru

Joined: 02/10/2012
Location: Australia
Posts: 1114
Posted: 07:57am 26 Jan 2019
Copy link to clipboard 
Print this post

Thanks Geoff,

I understand and appreciate your detailed explanation,

Best Regards,
panky.

PS. Thanks too, Jim, that is actually what I do to save as much space as possible.

My program on the MM+ takes 720 blocks on download so I am nearing the limit - lots of comments so I use crunch on load which brings it back to some 400 odd blocks.

... almost all of the Maximites, the MicromMites, the MM Extremes, the ArmMites, the PicoMite and loving it!
 
robert.rozee
Guru

Joined: 31/12/2012
Location: New Zealand
Posts: 2442
Posted: 11:33am 26 Jan 2019
Copy link to clipboard 
Print this post

  Geoffg said   This is to do with the memory allocation algorithm. When you declare a string MMBasic will ask the memory management system for some RAM to store the string. This is allocated in chunks of 256 bytes which, in part, is why strings are limited to 255 bytes (the extra byte is used to record the string length). Even if you ask for 16 bytes you will still get 256 bytes


why do floats (4-bytes each) and integers (8-bytes each) not suffer from the same problem?


cheers,
rob :-)
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 10315
Posted: 11:42am 26 Jan 2019
Copy link to clipboard 
Print this post

  Quote  why do floats (4-bytes each) and integers (8-bytes each) not suffer from the same problem?


Float and integer arrays do. So "DIM INTEGER a(1)" costs 256 bytes but so does "DIM INTEGER a(31)"

Simple float and integer variables are stored in the variable table so just cost one variable. The union statement says that the 8 allocated bytes (based on the longest variable declaration - long long int) can be used by any of the variable types

struct s_vartbl { // structure of the variable table
char name[MAXVARLEN]; // variable's name
char type; // its type (T_NUM, T_INT or T_STR)
char level; // its subroutine or function level (used to track local variables)
unsigned char size; // the number of chars to allocate for each element in a string array
short int dims[MAXDIM]; // the dimensions. it is an array if the first dimension is NOT zero
union u_val {
MMFLOAT f; // the value if it is a float
long long int i; // the value if it is an integer
MMFLOAT *fa; // pointer to the allocated memory if it is an array of floats
long long int *ia; // pointer to the allocated memory if it is an array of integers
char *s; // pointer to the allocated memory if it is a string
} val;
};
 
robert.rozee
Guru

Joined: 31/12/2012
Location: New Zealand
Posts: 2442
Posted: 12:50pm 26 Jan 2019
Copy link to clipboard 
Print this post

aha, i think i understand!

so is there a limit to the maximum number of simple variables allowed? or does the table just grow from the bottom of available RAM upwards, while the memory allocated for strings and arrays grows from the top of RAM down?

then i presume there will be a fixed-size table for subroutines/functions (100 max on mx170), and fixed-size stacks for gosub/return, for/next, do/loop, and if/else/endif?

a diagram showing all this would be a really useful addition to the micromite manual, to allow users a clearer understanding of how RAM is used. while it may be beyond some users to make sense of, others would no doubt find it useful.


cheers,
rob :-)
 
robert.rozee
Guru

Joined: 31/12/2012
Location: New Zealand
Posts: 2442
Posted: 02:11pm 26 Jan 2019
Copy link to clipboard 
Print this post

it looks like each entry in the variable table is around 59 bytes:
32 + 1 + 1 + 1 + (8*2) + 8

this could be significantly reduced by instead of storing the variable name (32 bytes), one were to store a pointer (8 bytes) to the location in flash where the variable is declared plus a 1-byte name length.

this would reduce each entry from 59 bytes down to 36 bytes.


cheers,
rob :-)
 
Geoffg

Guru

Joined: 06/06/2011
Location: Australia
Posts: 3292
Posted: 02:25pm 26 Jan 2019
Copy link to clipboard 
Print this post

Saving 23 bytes is trivial when the free RAM is 50K and the cost would be:
- Slower searches
- The extra flash to handle various terminators
- It would break programs that rely on that structure (there are some)
Geoff Graham - http://geoffg.net
 
JohnS
Guru

Joined: 18/11/2011
Location: United Kingdom
Posts: 4044
Posted: 04:17pm 26 Jan 2019
Copy link to clipboard 
Print this post

I suppose someone desperate to save some RAM and willing to make the internals slower and more complex (and perhaps with more bugs which are harder to find) could ask for the source and make the changes to their local MMBasic.

Or use a CPU with more RAM.

John
 
Print this page


To reply to this topic, you need to log in.

The Back Shed's forum code is written, and hosted, in Australia.
© JAQ Software 2025