Author | Topic: Recursive function ends with xppFatal? | |
---|---|---|
Sander Elias | Recursive function ends with xppFatal? on Wed, 18 Mar 2015 07:12:06 +0100 Hi All, I like to solve some problems with recursive functions, and ran into a snag. the following code will exit with a xppfatal? PROCEDURE Main local arr := {} local max := 2000 local x := 0 local nSum := 0 /* we use the ansi charset by default */ SET CHARSET TO ANSI for x = 1 to max aAdd(arr,x) next nSum := recursiveSum(arr,1,max) qout("sum"+ str(nSum)) inkey(10) RETURN function recursiveSum(arr,index,stop,prev) default index to 1, prev to 0 if index > stop return prev endif return recursiveSum(arr,index+1,stop,prev+arr[index]) I'm assuming I run out of the stack, but already with less then 2000 iterations? How can I enlarge my stack, and what are the trade-offs? Regards Sander Elias -------------------------------------------- also a member off the XXP (http://www.xxp.nl) | |
Hubert Brandel | Re: Recursive function ends with xppFatal? on Wed, 18 Mar 2015 08:16:50 +0100 Am 18.03.2015 um 07:12 schrieb "Sander Elias": > How can I enlarge my stack, with a parameter from ALINK /ST[ACK]:<max>[,<min>] | |
Sander Elias | Re: Recursive function ends with xppFatal? on Wed, 18 Mar 2015 09:46:11 +0100 Hi Hubert, Thanks for the info! However, that leaves the question, how large should I make it. And what is the trade of? I'm assuming there must be one if it's this small to begin with.. Also, their is some lack in documentation. What is the default size? Why is that size picked? Regards Sander Elias -------------------------------------------- also a member off the XXP (http://www.xxp.nl) | |
Thomas Braun | Re: Recursive function ends with xppFatal? on Wed, 18 Mar 2015 15:08:36 +0100 Sander Elias wrote: > However, that leaves the question, how large should I make it. And what > is the trade of? I'm assuming there must be one if it's this small to > begin with.. Also, their is some lack in documentation. What is the > default size? Why is that size picked? According to the docs, the default maximum value is 1 MB: > /ST[ACK]:<max>[,<min>] This option sets the stack size of an Xbase++ > application. <max> is a numeric value indicating the maximum stack size > in bytes (default is 1 MB), while <min> optionally defines the stack > size at program start. This means that the minimum stack size is <min> > bytes and it can grow dynamically at runtime to a maximum size of <max> > bytes. So if I where you I would increase it to 2 MB and see what happens Unfortunately this still leaves all your other questions unanswered. I rember that there has been discussions about this switch several times in the past, maybe just do a search in the news group. Thomas | |
Werner Martl | Re: Recursive function ends with xppFatal? on Wed, 18 Mar 2015 11:05:02 +0100 Am 18.03.2015 um 07:12 schrieb "Sander Elias": > Hi All, > > I like to solve some problems with recursive functions, and ran into a snag. > the following code will exit with a xppfatal? > > PROCEDURE Main > local arr := {} > local max := 2000 > local x := 0 > local nSum := 0 > /* we use the ansi charset by default */ > SET CHARSET TO ANSI > > for x = 1 to max > aAdd(arr,x) > next > nSum := recursiveSum(arr,1,max) > qout("sum"+ str(nSum)) > inkey(10) > RETURN > > function recursiveSum(arr,index,stop,prev) > default index to 1, prev to 0 > if index > stop > return prev > endif > return recursiveSum(arr,index+1,stop,prev+arr[index]) > > I'm assuming I run out of the stack, but already with less then 2000 iterations? How can I enlarge my stack, and what are the trade-offs? > Regards > Sander Elias > -------------------------------------------- > also a member off the XXP (http://www.xxp.nl) > Hi Elias, replace > for x = 1 to max > aAdd(arr,x) > next with arr := array(max) afill(arr, 0) ==> much faster, less memory-leaks. Best regards, Werner | |
Thomas Braun | Re: Recursive function ends with xppFatal? on Wed, 18 Mar 2015 11:40:39 +0100 Werner Martl wrote: > Hi Elias, > > replace > > > for x = 1 to max > > aAdd(arr,x) > > next Werner, the result of your code is not the same as the code above! Your code sets each element of the array to 0. Elias' code fills the array with a sequence of consecutive numbers 1,...,max To make it identical, you need to do this: arr := array(max) For x = 1 TO max arr[x] := x Next I did not test if this is actually faster or using less memory as the original code. regards Thomas | |
Sander Elias | Re: Recursive function ends with xppFatal? on Wed, 18 Mar 2015 13:45:55 +0100 Hi Werner, Thomas, As Thomes remarked, the code fills the array with different numbers. Actually my code sample is not about the for-next loop. It is about the problem with recursive functions. And this was the simplest sample I could come up with. I can't complain about array speed in xbase anymore (big progress into that in 2.0) I did some simple timings. On my computer I can create an array 10.000.000(no, not a typo!) the same way as the above sample, and then traverse it summing it up in approximate 4 seconds. That is an HUGE improvement of 1.9 Regards Sander Elias -------------------------------------------- also a member off the XXP (http://www.xxp.nl) | |
Thomas Braun | Re: Recursive function ends with xppFatal? on Wed, 18 Mar 2015 15:05:05 +0100 Sander Elias wrote: > Hi Werner, Thomas, > > As Thomes remarked, the code fills the array with different numbers. > Actually my code sample is not about the for-next loop. It is about the problem with recursive functions. Probably Werner supects some memory leak to be the cause for your problem (which I doubt it is) Did the /ST switch help to mitigate the problem? Thomas | |
Sander Elias | Re: Recursive function ends with xppFatal? on Wed, 18 Mar 2015 16:24:51 +0100 >Did the /ST switch help to mitigate the problem? Yes it did. I upped it to 10Mb. Now I can recursively traverse at a usable level (20.000 seems to run ok now, that is in a test program, with nothing else going on!) at 21000 there is still a fatal, which still is very bad. However, I'm still in the dark on the flip side of this? Just some extra memory? Thats not a bad deal, but what is the catch? But now at least I can use stuff like this in most cases without too much worrying. function reduce(bBlock,arr,index,prev) static last default index to 1, prev to 0 if index == 1 last := len(arr) endif if index > last return prev endif return reduce(bBlock,arr,index+1,eval(bBlock,arr[index],prev)) nSum:= reduce({|c,pre| c+pre}, arr,1,max) nMax:= reduce({|c,pre| max(c,pre)}, arr,1,max) With the speed of 2.x this works more then fast enough. Regards Sander Elias -------------------------------------------- also a member off the XXP (http://www.xxp.nl) | |
Thomas Braun | Re: Recursive function ends with xppFatal? on Thu, 19 Mar 2015 09:03:20 +0100 Sander Elias wrote: > with nothing else going on!) at 21000 there is still a fatal, which > still is very bad. Yes - a proper error message would be the preferred way instead of leaving the developer alone in the dark with some rather cryptic and undocumented fatal error Thomas |