I spy a number of memory leaks in PVPITEMS, and I'm sure there are some in the other programs as well. A memory leak happens when you Goto out of an If/Then/End, If/Then/Else/End, For/End, While/End, or Repeat/End structure. Because you Goto out of the structure, the calculator is remembering that it needs to find the End for that structure, but it never finds it. The more Ends that it needs to keep track of (that it will never see), the slower the program goes, until it eventually runs out of space to keep track of those Ends.
So if I understand it right, the following outline of code should produce a memory leak:
Code:
:While ~~~
    :If ~~~
    :Then
        :Repeat ~~~
            :~~~~~
            :~~~~~
            :If ~~~
            :Goto A
            :~~~~~
        :End
        :Repeat ~~~
            :~~~~~
        :End
    :End
:End
:~~~~~
:Lbl A
But If I do something like the following, would it prevent a memory leak?
Code:
:DelVar X
:While ~~~
    :If ~~~
    :Then
        :Repeat ~~~
            :~~~~~
            :~~~~~
            :If ~~~
            :1 -> X
            :If X
            :Then
                :Else
                :~~~~~
            :End
        :End
        :If X
        :Then
            :Else
            :Repeat ~~~
                :~~~~~
            :End
        :End
    :End
:End
:If X
:Goto A
:~~~~~
:Lbl A
It will undoubtedly make the code longer, more complex, and consume more RAM, but hopefully it will keep it from crashing.
Also, won't changing programs inside of a loop also cause a memory leak, so I'll need to do the same for them?

Edit: Would this also work?

Code:
:While ~~~
    :If ~~~
    :Then
        :Repeat ~~~
            :~~~~~
            :~~~~~
            :If ~~~
            :Goto A
            :~~~~~
        :End
        :Repeat ~~~
            :~~~~~
        :End
    :End
:End
:~~~~~
:While 0
    :While 0
        :While 0
            :Lbl A
        :End
    :End
:End
I believe I have a pretty good understanding of what a memory leak is, I just don't know the best way to fix one.
FrozenFire49 wrote:
Would this also work?
Code:
:While ~~~
    :If ~~~
    :Then
        :Repeat ~~~
            :~~~~~
            :~~~~~
            :If ~~~
            :Goto A
            :~~~~~
        :End
        :Repeat ~~~
            :~~~~~
        :End
    :End
:End
:~~~~~
:While 0
    :While 0
        :While 0
            :Lbl A
        :End
    :End
:End

I just tested this on my TI-73, and I can tell you why it doesn't quite work. The BASIC interpreter sees the :End after the :Lbl A, and believes it just reached the end of your loop up above. If you can exit those loops where you use Goto, then you can use this general solution (though it isn't pretty). Since the BASIC implementation doesn't strictly care about starting/ending loops, you don't need the While 0 statements if you properly handle program control flow to never parse Lbl A outside of the place you used Goto at. Since it's late and I'm tired, what I'm trying to say is that the BASIC interpreter sets aside a bit of memory to record where a code block (terminated by :End) begins, and it does not look ahead to find those code blocks -- when it reaches an :End statement, it will accept that as the end of the current code block it is in.

I should introduce some definition of nesting levels here: a nesting level is how many code blocks you are in. For example, in this code segment:

Code:
:If 1
:Then
:  Output(1,1,"HAI"
:  While 1
:    Disp "HEY WUTS UP"
:  End
:End
the Output statement is one nesting level deep, while the Disp statement is two levels deep. You can Lbl...Goto if you stay at the same nesting level if you aren't using any loops. If you do have loops, you may get unexpected (or expected, depending on program structure) behavior if your loop finds that :End statement after the Goto, you want to exit the loop, and your exit condition doesn't work for the loop. You'll have to do something like this code segment in order to exit a loop with Goto without leaking memory:
Code:
:1
:While [blah] and Ans
:  Disp "DO STUFF"
:  If [I want out of the loop]
:    Goto 1
:  1 (or anything that evaluates to not 0)
:End
:Goto E
:Lbl 1
:Disp "YAY I LEFT LOOP"
:0
:End
:Lbl E

I can't really show nesting levels here accurately since I do abuse End (more than one End for a single loop), but the BASIC interpreter doesn't know the difference between the two -- it just comes across an End statement. If you stay in the loop, the line :1 sets Ans to 1; otherwise, Ans is set to 0 when you exit the loop. When the interpreter sees that :End, it looks at the While condition again, and sees that it needs to stop the loop. Program execution picks up where it left off, which is the line after whichever :End it encountered. This is perfectly valid and quite fast if you only have If statements, but with loops it becomes more difficult.

But, you can see this is an ugly solution to a simple problem. While it does an excellent job at showing what the TI-BASIC parser does, it isn't optimal; we used an extra label for each instance of this, plus we use either Ans or an extra variable. A few ways I do Goto-in-loops looks like these:

Code:
:While [condition] and [exit-condition]
:  Disp "DO COOL THINGS"
:  1
:  If [fun-stuff]
:  Then
:    Disp "MORE STUFF"
:    [not-exit-condition]
:  End
:  If Ans
:  Then
:    Disp "REST OF LOOP"
:  End
:End
It's not very fast though. I'm sure TIBasicDev or someone else here can give a much better solution -- take this first one with a heaping handful of salt.

If I have to do a lot of branching, I just eliminate all the loops and replace them with well-named label-goto loops:

Code:
:For(X,1,50
:  getKey→K
:  If K=11
:    Goto K1
:  If K=12
:    Goto K2
:  If K=105
:    Goto K3
:End

can become

Code:
:1→X
:Lbl KL
:getKey→K
:If K=11
:  Goto K1
:If K=12
:  Goto K2
:If K=105
:  Goto K3
:IS>(X,50
:Goto KL

By using IS>(, I do not enter any nesting levels, and thus I do not leak any memory.
  
Register to Join the Conversation
Have your own thoughts to add to this or any other topic? Want to ask a question, offer a suggestion, share your own programs and projects, upload a file to the file archives, get help with calculator and computer programming, or simply chat with like-minded coders and tech and calculator enthusiasts via the site-wide AJAX SAX widget? Registration for a free Cemetech account only takes a minute.

» Go to Registration page
Page 2 of 2
» All times are UTC - 5 Hours
 
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

 

Advertisement