[PB5.20b19] Recursion plus SELECT = Invalid Memory Access
Posted: Sat Sep 14, 2013 7:08 am
I am running PB5.20 beta 19 LTS (x64) on Mint 15 (Ubuntu variant).
If I use a SELECT...ENDSELECT statement with an embedded GOTO in a procedure that is recursive (calls itself), I get an error message after the first recursion. If I replace the SELECT...ENDSELECT with a IF...ELSEIF...ELSE...ENDIF structure with an embedded GOTO, it runs fine. The following code shows procedure 'recurse1' running fine, but procedure 'recurse2' will crash the program when the procedure tries to exit using either a Procedure Return or EndProcedure statement.
This example is not intended to discuss the merits of coding style, but is to illustrate that a valid set of basic instructions causes a memory access problem when a SELECT statement combined with a GOTO statement causes the program to crash.
If I use a SELECT...ENDSELECT statement with an embedded GOTO in a procedure that is recursive (calls itself), I get an error message after the first recursion. If I replace the SELECT...ENDSELECT with a IF...ELSEIF...ELSE...ENDIF structure with an embedded GOTO, it runs fine. The following code shows procedure 'recurse1' running fine, but procedure 'recurse2' will crash the program when the procedure tries to exit using either a Procedure Return or EndProcedure statement.
Code: Select all
EnableExplicit
Procedure.i recurse1(cnt.i)
; create some variables unique to this instance of recursion
Protected rc.i
Protected x.i
MessageRequester("Test","Recurse1 "+Str(cnt))
If cnt = 0
rc = cnt + 1 ; do some work
x = recurse1(rc) ; recursively call myself
Else
rc = cnt + 1 ; do some work
Goto AllDone1
EndIf
x = x + 1 ; do some work
AllDone1:
; This routine works properly
ProcedureReturn rc
EndProcedure
Procedure.i recurse2(cnt.i)
; create some variables unique to this instance of recursion
Protected rc.i
Protected x.i
MessageRequester("Test","Recurse2 "+Str(cnt))
Select cnt
Case 0
rc = cnt + 1 ; do some work
x = recurse2(rc) ; recursively call myself
Default
rc = cnt + 1 ; do some work
Goto AllDone2 ; this GOTO causes the error when the procedure exits.
EndSelect
x = x + 1 ; do some work
AllDone2:
; Error: INVALID MEMORY ACCESS HERE
ProcedureReturn rc
EndProcedure
Define x.i
x = recurse1(0)
x = recurse2(0)
MessageRequester("Test","Done")