Board index » delphi » Recusive Call causes crash

Recusive Call causes crash

I have written a routine for a ButtonClick event.  If the general
processing of the works, I exit the routine.  If the routine fails, I
step to the next thing that I want to process and call the ButtonClick
event from within itself.  I have found that at around 18 recursive
calls to the ButtonClick event, my program crashes.  I have searched
for documentation on the subject of recursive functions, but haven't
found anything.

I also tried moving the routine into its own procedure that calls
itself and get the same result.

Any ideas?

  Anthony

 

Re:Recusive Call causes crash


Quote
On Sun, 12 May 1996 03:38:22 GMT, dia...@intnet.net wrote:
>I have written a routine for a ButtonClick event.  If the general
>processing of the works, I exit the routine.  If the routine fails, I
>step to the next thing that I want to process and call the ButtonClick
>event from within itself.  I have found that at around 18 recursive
>calls to the ButtonClick event, my program crashes.  I have searched
>for documentation on the subject of recursive functions, but haven't
>found anything.

>I also tried moving the routine into its own procedure that calls
>itself and get the same result.

>Any ideas?

>  Anthony

Probably the most common causes for a crash in a recursive program is the stack
filling up. Unfortunately with Delphi there is no easy way to tell how much
stack space is used up for each call. I believe that you can increase the stack
size and see if your program will run through more iterations before bombing.

Note that all parameters passed to the called program must be saved on the stack
on each call, so if you can keep the calling parameter list short you won't use
up space so fast. You should also be sure, where possible, that items are passed
by reference so that only a pointer need be saved on the stack for each call.
That's especially important in passing arrays.

Good luck,
{*word*106}
See my home page at:
http://www.netcom.com/~dickmac for "The Better of Boulder County"
(not to be confused with "The Best of Boulder")

Re:Recusive Call causes crash


Quote
In article <4n3cbb$...@mercury.IntNet.net> dia...@intnet.net writes:
>I have written a routine for a ButtonClick event.  If the general
>processing of the works, I exit the routine.  If the routine fails, I
>step to the next thing that I want to process and call the ButtonClick
>event from within itself.  I have found that at around 18 recursive
>calls to the ButtonClick event, my program crashes.  I have searched
>for documentation on the subject of recursive functions, but haven't
>found anything.
>I also tried moving the routine into its own procedure that calls
>itself and get the same result.

You're blowing your stack.  :-)

When you call a routine recursively, the status of the existing function
instance is placed on the stack for an eventual return.  If the stack limit is
exceeded, then (at minimum) your program will die.

It sounds to me like you have an iterative, rather than a recursive task.  
Your button might be doing:

        itemToProcess := 0;
        itWorked := false;
        while (itemToProcess <= numberOfItems) and (not itWorked) do
           if ProcessItem(itemToProcess)
              then itWorked := true
              else Inc(itemToProcess);

This is a non-recursive solution:  ProcessItem does not call itself.

/mr/

Re:Recusive Call causes crash


Quote
dia...@intnet.net wrote:
>I have written a routine for a ButtonClick event.  If the general
>processing of the works, I exit the routine.  If the routine fails, I
>step to the next thing that I want to process and call the ButtonClick
>event from within itself.  I have found that at around 18 recursive
>calls to the ButtonClick event, my program crashes.  I have searched
>for documentation on the subject of recursive functions, but haven't
>found anything.
>I also tried moving the routine into its own procedure that calls
>itself and get the same result.

Recursive routines eat up a lot of stack space in a hurry, especially
if they contain parameters or local variables, or perform string
operations (the compiler allocates string temporaries on the stack)

I assume you're talking about a Delphi 1.0 application.  You have only
16k of stack space to work with in 16 bit applications, and in a
recursive routine you can run through 16k in a hurry.  (Available
stack space is measured in megabytes in Delphi 2.0 apps)

Check your recursive routine carefully for string variables, string
operations, and local variables.  My guess is that strings are eating
you alive.

-Danny

Re:Recusive Call causes crash


Quote
> Re: Recusive Call causes crash
> Whats ++ short for? Does that mean add nothing to var1 twice?
> Looks like it to me.

> Dave

It comes from PDP/11 assembler Digital's aging (but profitable) line of
16 bit computers.

    (r1)++  

would automatically increment the contents of the register while letting
you use the value. There were pre and post increments and decrements. they
were written:
   --(xx) or (xx)--
   ++(xx) or (xx)++

Brian Kernighan liked the idea and used it in his C language. C contains
numerous instances of shorthand (idioms).

   counter += 5;

would add 5 to the counter instead of counter = counter + 5;

Bill Touchstone
ycc...@gate.net

Re:Recusive Call causes crash


Quote
ycc...@gate.net (Bill Touchstone) wrote:
>> Re: Recusive Call causes crash
>> Whats ++ short for? Does that mean add nothing to var1 twice?
>> Looks like it to me.

>> Dave

>It comes from PDP/11 assembler Digital's aging (but profitable) line of
>16 bit computers.
>    (r1)++  
>would automatically increment the contents of the register while letting
>you use the value. There were pre and post increments and decrements. they
>were written:
>   --(xx) or (xx)--
>   ++(xx) or (xx)++

Hm. If I remember right, the actual PDP11 instructions implemented
(xx)++ and --(xx) but not (xx)-- and ++(xx).

Yup. Looked it up on an old programing card.
<nostalgia>There were 3 bits defining the addressing modes,
and the code was written with one '+':
0  R    register
1 (R)   register deferred
2 (R)+  auto-increment
3 @(R)+ auto-increment deferred
4 -(R)  auto-decrement
5 @-(R) auto-decrement deferred
6 X(R)  index
7 @X(R) index deferred

Some of these could be used with the PC and
SP too, e.g., JSR @(SP)+ could be used for a
co-routine subroutine call. It would call the
routine whose address was on top of the stack,
popping that off and pushing the return address
on, so the co-routine would be in a position
to do the same back. You have to get tricky to
do that in C ;-) It was a nice machine to program
in assembler. </nostalgia>
[...]

Regards,
Bengt Richter

Re:Recusive Call causes crash


In article <4njn8c$...@news.accessone.com>, b...@accessone.com says...
<Snip>

Bengt,

Boy does that bring back memories. I worked for DEC in Dallas for 12 years
before 60,000 or so of us were given our walking papers. I did an entire
project (40,000+) lines of code in PDP-11 Assembler (RSX-11S) downloaded from
VMS. That turned out to be one of the best projects I have ever done and one
that was the most enjoyable. We did a little more than 2000 interrupts per
second with this code.

Talk about nostalgia! The PDP-11 Assembler was a great language.

Jerry

Re:Recusive Call causes crash


Quote
In article <4ndqrp$...@pdn.eng.paradyne.com>, Bill Touchstone (ycc...@gate.net) writes:
>    (r1)++  

>would automatically increment the contents of the register while letting
>you use the value. There were pre and post increments and decrements. they
>were written:
>   --(xx) or (xx)--
>   ++(xx) or (xx)++

>Brian Kernighan liked the idea and used it in his C language. C contains
>numerous instances of shorthand (idioms).

>   counter += 5;

>would add 5 to the counter instead of counter = counter + 5;

It's interesting to see how languages evolve.  These days, even
Cobol compilers  support simple macros so I can define ++ to mean
ADD 1 TO, after which I can say ++i (yes, in Cobol, that's right)!

On the downside, Pascal recently added properties, so when I want to
say Inc(i) where i is a property, I just get an "invalid variable
reference" error or something such from the compiler, and in the
end I have to say i := i + 1 again...

--
Holger Friedrich
Chemnitz, Germany
E-Mail:         h...@glare.in-chemnitz.de
Second chance:  easy!glare...@thunder.hrz.tu-chemnitz.de

Re:Recusive Call causes crash


Quote
h...@glare.in-chemnitz.de (Holger Friedrich) wrote:

>In article <4ndqrp$...@pdn.eng.paradyne.com>, Bill Touchstone (ycc...@gate.net) writes:
>>    (r1)++  

>>would automatically increment the contents of the register while letting
>>you use the value. There were pre and post increments and decrements. they
>>were written:
>>   --(xx) or (xx)--
>>   ++(xx) or (xx)++

>>Brian Kernighan liked the idea and used it in his C language. C contains
>>numerous instances of shorthand (idioms).

>>   counter += 5;

>>would add 5 to the counter instead of counter = counter + 5;
>It's interesting to see how languages evolve.  These days, even
>Cobol compilers  support simple macros so I can define ++ to mean
>ADD 1 TO, after which I can say ++i (yes, in Cobol, that's right)!
>On the downside, Pascal recently added properties, so when I want to
>say Inc(i) where i is a property, I just get an "invalid variable
>reference" error or something such from the compiler, and in the
>end I have to say i := i + 1 again...

Yes, that is crazy.  Can't the compiler copy the property into a
memory variable long enough to operate on it as a memory variable, and
then assign the variable's value to the property after the expression
has been evaluated?  This would especially be helpful when trying to
pass properties as variable parameters.  Borland should at least be
able to do this for integer properties.

------------------------------
Tim Shea
City Software, Inc.
c...@citysoft.com
Hit any key to continue, any other to exit.

Re:Recusive Call causes crash


Tim Shea writes

Quote
> Can't the compiler copy the property into a
> memory variable long enough to operate on it as a memory variable, and
> then assign the variable's value to the property after the expression
> has been evaluated?

Think about what Inc(i) means for a property that uses custom read and
write methods. It's really.

        PropOwner.SetI(PropOwner.ReadI + 1);

I guess the compiler could be wired to do that, but it's not just as
simple as copying memory variable locations in all cases.

--
Gregory H. Anderson        | "I wander'd off by myself, In the
Crystal Ball/Star Gazer    |  mystical moist night-air, and from
Anderson Financial Systems |  time to time, Look'd up in perfect
g...@afs.com (NeXTmail OK) |  silence at the stars." Walt Whitman

Re:Recusive Call causes crash


Greg_Ander...@afs.com (Gregory H. Anderson) wrote:

Quote
>Tim Shea writes
>> Can't the compiler copy the property into a
>> memory variable long enough to operate on it as a memory variable, and
>> then assign the variable's value to the property after the expression
>> has been evaluated?
>Think about what Inc(i) means for a property that uses custom read and
>write methods. It's really.
>    PropOwner.SetI(PropOwner.ReadI + 1);
>I guess the compiler could be wired to do that, but it's not just as
>simple as copying memory variable locations in all cases.

Actually, I think it is that simple.  Think about what

Quote
>    PropOwner.SetI(PropOwner.ReadI + 1);

really means.  If the prop is an integer, the compiler is most likely
going to stash the return value of PropOwner.Read into a register, add
one to it, and then pass the new value to PropOwner.Set.  There is no
reason the compiler couldn't "forget" that it is dealing with a
property during the middle step (which could be a much more
complicated assignment of course, and during which the "property"
might be passed as a variable parameter to a function), and therefore
allow all the usual contructs like Inc, Dec, Succ, etc. with the
exception of @.

The compiler code that generates a "not a real variable reference"
error already detects this situation nicely.

The only good reason they didn't do this that I can think of is... if
you pass a property as a variable parameter to a routine, and that
routine uses @ on the parameter and stores the resultant address
somewhere that will outlive the routine (such as a global), after the
routine finishes and the temporary memory variables dissapears
(probably it lived on the stack) the address the routine fetched will
be garbage.

------------------------------
Tim Shea
City Software, Inc.
c...@citysoft.com
Hit any key to continue, any other to exit.

Other Threads