[comp.sys.mac.programmer] Think C Agony!

sean@eleazar.dartmouth.edu (Sean P. Nolan) (03/07/91)

Hi there.

I'm having a problem that is making my eyes cross and my head spin around 
on my shoulders. PLEASE, if you can help here let me know, I'm up against
a deadline!

The following code, run without the Think Debugger, crashes with an addr error
at the (**hclusterNew).LearningRate = (**network).DefaultBiasLearningRate
assignment. Now here's the trick. Put in a Debugger() command right before
the assignment, and both handles (hclusternew and network) are perfectly
valid, and no crash occurs! Take away the Debugger(), and there's a
reproducible crash. Also, the same code run under the Think Debugger does
not crash. Help!

I seem to remember something like this being discussed. Anyone? Anything?
Thanks....

--- Sean

	/* allocate bias matrix */
	if (!((**hclusterNew).prgbiasstruct =
		(BIASSTRUCT**) NewHandle(NumNodes * sizeof(BIASSTRUCT))))
		{
		DisposHandle(hclusterNew);
		return(FALSE);
		}
	(**hclusterNew).LearningRate = (**network).DefaultBiasLearningRate;
	(**hclusterNew).fBiasesFrozen = FALSE;
	RandomizeBiases(network,hclusterNew);

+----------------------------------------------------------------------------+
| Sean P. Nolan     |    sean@eleazar.dartmouth.edu     | "That's not a      |
| Dartmouth College |                                   |  baby, that's a    |
| Hinman Box 2658   |            SCALP 'EM!             |  Mr. Potatohead!"  |
| Hanover, NH 03755 |                                   |     --- A.W.O.T.M. |
+----------------------------------------------------------------------------+

d88-jwa@dront.nada.kth.se (Jon W{tte) (03/08/91)

	/* allocate bias matrix */
	if (!((**hclusterNew).prgbiasstruct =
		(BIASSTRUCT**) NewHandle(NumNodes * sizeof(BIASSTRUCT))))
                               ~~~~~~~~~

Be careful ! NewHandle moves memory, and you have a dereferenced
handle in **hclusterNew. In THINK C, this gets evaluated after
the function call, but not in all C compilers (I believe)...

		{
		DisposHandle(hclusterNew);
		return(FALSE);
		}
	(**hclusterNew).LearningRate = (**network).DefaultBiasLearningRate;

So what's "network" anyway ? It's hard to debug without knowing
how stuff is declared...

By the way, things that crash when run normally but don't when run
in the debugger usually don't initialize all the managers in the
right way.

(Check InitGraf, InitFonts, InitMenus, InitWindows, InitDialogs,
 TEInit for starters...)

						h+@nada.kth.se
						Jon W{tte
"The IM-IV file manager chapter documents zillions of calls, all of which
seem to do almost the same thing and none of which seem to do what I want
them to do."  --  Juri Munkki in comp.sys.mac.programmer

rmh@apple.com (Rick Holzgrafe) (03/09/91)

In article <1991Mar7.063549.14081@dartvax.dartmouth.edu> 
sean@eleazar.dartmouth.edu (Sean P. Nolan) writes:
>         if (!((**hclusterNew).prgbiasstruct =
>                 (BIASSTRUCT**) NewHandle(NumNodes * sizeof(BIASSTRUCT))))

With some compilers, this can fail. A simplified example is:
         (**h).f = NewHandle (20);
If the handle h is not locked, and if the compiler evaluates **h before 
calling NewHandle, then the value of **h may become incorrect when 
NewHandle shuffles the heap.

There are three possible solutions. (1) Lock the handle. (2) Use a 
temporary variable:
        Handle theNewHandle = NewHandle (20);
        (**h).f = theNewHandle;
or (3) some compilers avoid the whole issue by not evaluating the 
left-hand side of an assignment until the right-hand side has been 
evaluated - check your manual (and maybe play it safe anyway).

Hope this helps.

==========================================================================
Rick Holzgrafe              |    {sun,voder,nsc,mtxinu,dual}!apple!rmh
Software Engineer           | AppleLink HOLZGRAFE1          rmh@apple.com
Apple Computer, Inc.        |  "All opinions expressed are mine, and do
20525 Mariani Ave. MS: 3-PK |    not necessarily represent those of my
Cupertino, CA 95014         |        employer, Apple Computer Inc."