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.
» Forum
> Your Projects
So if I understand it right, the following outline of code should produce a memory leak:
Code:
But If I do something like the following, would it prevent a memory leak?
Code:
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:
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.
Code:
:While ~~~
:If ~~~
:Then
:Repeat ~~~
:~~~~~
:~~~~~
:If ~~~
:Goto A
:~~~~~
:End
:Repeat ~~~
:~~~~~
:End
:End
:End
:~~~~~
:Lbl A
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
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
- CVSoft
- Expert (Posts: 685)
-
- its late and im tired but here is an attempt at explanation
- 21 Oct 2015 12:50:48 am
FrozenFire49 wrote:
Would this also work?
Code:
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
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
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
» Go to Registration page
» Goto page Previous 1, 2
» View previous topic :: View next topic
» View previous topic :: View next topic
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
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