Path: utzoo!attcan!utgpu!jarvis.csri.toronto.edu!mailrus!cornell!rochester!uhura.cc.rochester.edu!giaccone From: giaccone@uhura.cc.rochester.edu (Tony Giaccone) Newsgroups: comp.sys.mac.programmer Subject: Stale Pointers Keywords: Lightspeed C Message-ID: <2394@ur-cc.UUCP> Date: 28 Jun 89 17:12:02 GMT Distribution: usa Organization: Univ. of Rochester, Computing Center Lines: 58 I've spent a little time recently trying to track down a problem with my Lightspeed C code. After a little investigation, I've come upon the following problem. I think it worth noting. In general it seems that if your asigning values returned from functions to fields of data structures pointed to handles you should make sure you lock the block before hand. In my case I was trying to allocate memory for a bitmap image, and I stored that Pointer in a structure pointed to by a handle. The C source code looks like this: (**myImage).rasI_image = (SIPtr) NewPtr(size); if ((**myImage).rasI_image == NULL) { Where myImage is a handle to a image data structure, and rasI_image is a pointer to unsigned char. Lightspeed C compiles this C code to the following code fragment: 1 MOVEA.L $FE8E(A5), A0 ; $FE8E(A5) is the displacment off the ; stack where the local variable ; myImage is found. 2 CLR.L -(A7) 3 MOVE.L $FFFC(A6),-(A7) ; $FFFC(A6) is the local variable size 4 MOVE.L (A0),$FFD6(A6) ; $FFD6(A6) is not one of my local ; variables. 5 JSR ^$079528 ; Do the NewPtr 6 MOVEA.L (A7)+,A0 ; Pop the Return Code 7 MOVEA.L $FFD6(A6),A1 ; DeRefernce the Pointer. 8 MOVE.L A0,$0008(A1) ; Store the pointer in the myImage ; Data Structure 9 MOVEA.L $FE8E(A5),A0 ; Get the handle 10 MOVEA.L (A0),A0 ; Dereference the Handle 11 TST.L $0008(A0) ; Now, this code works fine the first time I execute it, I because the heap doesn't get shuffled. However, the next time I try to execute it, a serious problem occurs. On line 1 the value of the handle for myImage is placed in register A0. Then on line 4 that value is dereferenced, and stored as a displacement $FFD6 off register A6. That dereference occurs before the call to NewPtr. During NewPtr the handle for the block of memory that $FE8E(A5) contains changes. Now, when the pointer value returned by NewPtr is stored, the address used in $FFD6(A6) is used (which is no longer correct becuase of the heap shuffle caused by NewPtr). Now obviously the simple work around is to lock the block pointed to by myImage before I make the call to NewPtr (and in fact that is what I do). Still it seems odd that Lightspeed C should do part of the dereference before the call, and the other part after the call. What do you think? Tony Giaccone tonyg@cvs.rochester.edu