06-26-2017, 10:06 PM
This one's a bit long, sorry in advance!
As mentioned in the support forum, I've been having problems with my program growing unstable and crashing after a while. With your help (thanks!) I've narrowed the issue down to a single routine (and possibly a single line, but we'll get to that in a minute) which seems to be causing something bad to happen to the heap and/or memory.
I've extracted the offending routine out into the following program:
I'm compiling with:
-t -B -a --array-base=1 --string-base=1 --strict-bool --explicit
Apologies for the untidy appearance of the code, part of it's ripped straight from my game and the rest I wrote to support this test. The subroutine at line 8500 is supposed to generate six random alien names by taking a base array of 20 partial strings, then randomly choosing 12 of them and joining them together in pairs (perhaps also including a hyphen or apostrophe).
I've removed the random elements because they don't seem to affect the result, so in this test the same names will be generated each time. I've also introduced a lot of calls to a routine that prints the available memory and waits for you to press a key - the number displayed on the bottom line of the display shows you where you are in the code at any moment.
If you run the program and keep pressing a key, you will see that the numbers change as the names are generated but you're never really short of heap space. However, it's unlikely you'll make it through to the end of all six names without either the heap display going crazy and displaying huge numbers (usually between steps 6 and 7) or screen corruption appearing and the program crashing (usually but not always between steps 3 and 4).
I've tried altering the heap size and it doesn't seem to make any difference - even using a 10k+ heap it crashes in the same way.
What *does* make a difference (and I have no idea why) is removing line 8545. This is supposed to capitalise the first letter of the name (done in the Sinclair BASIC way). With that line in, the program fails almost every time. REM that line out and it works perfectly, but I don't know why. I've tried taking that single line and writing another test program around that alone, but I can't make it fail outside of this specific context.
Knowing that, I could probably work around the issue but I'm a bit worried I'd be leaving a potential bug unfixed if I did. It's also possible I've done something crazy and illegal here, in which case I'd love to know what it is so that I don't do it again! Let me know if anything doesn't make sense or you need anything else! And thanks, as always.
As mentioned in the support forum, I've been having problems with my program growing unstable and crashing after a while. With your help (thanks!) I've narrowed the issue down to a single routine (and possibly a single line, but we'll get to that in a minute) which seems to be causing something bad to happen to the heap and/or memory.
I've extracted the offending routine out into the following program:
Code:
#include <alloc.bas>
DIM i,q,n as ubyte
DIM st$, k$ as string
DIM pee$(20) as string
DIM name$(6) as string
test()
sub printmem(num as ubyte)
dim f, m as uinteger
f = memavail
m = maxavail
print at 22,0; ink 6; paper 2; flash 1;str$(f);" ";at 22,15;str$(m);" "
print at 23,0;str$(num)
go sub 9500
end sub
sub initarrays()
pee$(1)="nok"
pee$(2)="fra"
pee$(3)="gog"
pee$(4)="frak"
pee$(5)="tut"
pee$(6)="zex"
pee$(7)="gal"
pee$(8)="shun"
pee$(9)="ren"
pee$(10)="kal"
pee$(11)="sun"
pee$(12)="xox"
pee$(13)="yen"
pee$(14)="soo"
pee$(15)="arc"
pee$(16)="qir"
pee$(17)="oon"
pee$(18)="tak"
pee$(19)="raak"
pee$(20)="wyk"
end sub
sub test()
initarrays()
do
cls
go sub 8500
loop
end sub
8499 REM alien names
8500 printmem(1): LET i=1: printmem(2)
8510 FOR n=1 TO 6: LET st$=pee$(i): printmem(3)
8520 LET q=INT (RND*9)+1
8530 IF q<=3 THEN LET st$=st$+"'": GO TO 8540: END IF
8535 IF q>=7 THEN LET st$=st$+"-": END IF
8540 printmem(4): LET i=i+1: LET st$=st$+pee$(i): LET i=i+1: printmem(5)
8545 IF CODE (st$(1))>96 THEN LET st$(1)=CHR$ ( CODE (st$(1))-32): END IF
8550 printmem(6): LET name$(n)=st$: printmem(7): print at n,0;name$(n): printmem(8): NEXT n
8560 printmem(9): RETURN
9499 REM get keypress
9500 IF INKEY$<>"" THEN GO TO 9500: END IF
9510 LET k$=INKEY$: IF k$="" THEN GO TO 9510: END IF
9520 RETURN
I'm compiling with:
-t -B -a --array-base=1 --string-base=1 --strict-bool --explicit
Apologies for the untidy appearance of the code, part of it's ripped straight from my game and the rest I wrote to support this test. The subroutine at line 8500 is supposed to generate six random alien names by taking a base array of 20 partial strings, then randomly choosing 12 of them and joining them together in pairs (perhaps also including a hyphen or apostrophe).
I've removed the random elements because they don't seem to affect the result, so in this test the same names will be generated each time. I've also introduced a lot of calls to a routine that prints the available memory and waits for you to press a key - the number displayed on the bottom line of the display shows you where you are in the code at any moment.
If you run the program and keep pressing a key, you will see that the numbers change as the names are generated but you're never really short of heap space. However, it's unlikely you'll make it through to the end of all six names without either the heap display going crazy and displaying huge numbers (usually between steps 6 and 7) or screen corruption appearing and the program crashing (usually but not always between steps 3 and 4).
I've tried altering the heap size and it doesn't seem to make any difference - even using a 10k+ heap it crashes in the same way.
What *does* make a difference (and I have no idea why) is removing line 8545. This is supposed to capitalise the first letter of the name (done in the Sinclair BASIC way). With that line in, the program fails almost every time. REM that line out and it works perfectly, but I don't know why. I've tried taking that single line and writing another test program around that alone, but I can't make it fail outside of this specific context.
Knowing that, I could probably work around the issue but I'm a bit worried I'd be leaving a potential bug unfixed if I did. It's also possible I've done something crazy and illegal here, in which case I'd love to know what it is so that I don't do it again! Let me know if anything doesn't make sense or you need anything else! And thanks, as always.