Handles 2
Volume Number: 12 Issue Number: 5$ !Column Tag: Programming Workshop Memory Madness Getting a grip on handles #By Peter N Lewis, Perth, Australia U Note: Source code files accompanying article are located on MacTech CD-ROM or· source code disks. Introduction LUsing the Memory Manager’s handles effectively is a very important part of Nprogramming on the Macintosh. Using them badly is also a prime cause of many Ssystem crashes. This article describes the difference between memory and resource Mhandles, and operations on them that you should use or avoid. After a brief Vintroduction to the Macintosh memory model, I’ll list a bunch of rules or guidelines *along with the reasoning behind them [1]. Background XIf you know the basics of pointers, handles, resources and so forth, you can skip on to [the next section. I’ll try to keep this reasonably simple, but if you don’t know what a Zpointer is, you should probably skip this whole article and go buy a beginner’s guide to programming. $LOn the Macintosh, the Memory Manager (the system software which keeps track Pof all memory) divides the available RAM (including virtual memory) into chunks Rcalled “heap zones”. When your application is launched, you are allocated some Xmemory as a single heap zone (the size of this heap is defined by the “Get Info” size Zyou set in the Finder or originally in the SIZE resource of your application). You use PMemory Manager routines to allocate or release memory in your application zone, Yeither directly with routines like NewPtr and NewHandle, or indirectly with routines Xlike GetResource. Lots of routines allocate memory in your heap, but this article is Kgoing to concentrate only on the Memory Manager and the Resource Manager. % OSimilarly, you can allocate memory and create your own heap zones, and you can1 Lallocate memory outside your own heap zone (either in the System Zone or as= BTemporary Memory), but I’ll stick to just your application zone.N$QThe simplest way to allocate memory is to use the NewPtr routine. You tell itZ Vhow many bytes you want, and it returns a pointer to the memory, or nil (NULL) iff Tthere was not enough memory available. One problem with pointers is that you oftenr Zcan’t resize them. Even if there is lots of free space left in the heap, there might be~ Qsomething allocated in the memory just after the pointer, so resizing it quickly Cbecomes impossible. A solution to this problem is to use handles. $QA handle is a Memory Manager structure which is basically a pointer to a pointer W(the first pointer is a handle, the second one is called a master pointer). Your code Uremembers the handle, and then, to resize it, the Memory Manager can free the master Rpointer and allocate new space anywhere in the heap. You allocate a handle using 5NewHandle and you release it using DisposeHandle.‹$LOne of the most common times that you will use handles is when dealing withË Uresources. All resources on the Macintosh are allocated as handles. You allocate aÙ Uresource handle using GetResource and you release it using ReleaseResource or by closing the resource file. Real Pointers and Handles, TThe Mac operating system is not known for robust APIs (particularly those APIs that8 Phave been with us since 1984). If you pass invalid parameters to the operatingD Ysystem, at best it will do nothing useful, at worst it will crash the system and corruptP Ypeople’s data. So it is very important to ensure that you are always playing nice with\ the Memory Manager.v 81 Always check whether a memory allocation returns nil. $UI know you’ve heard this a thousand times before, but it can’t be repeated enough. ZNewPtr, NewHandle, GetResource, and so forth can all fail and return nil. If your Ycode blissfully ignores this fact, you are going to go down in flames. It is especially important not to pass the nil returned by NewPtr to DisposePtr; that is a sure way to Udie (passing nil to DisposeHandle on the other hand is perfectly safe). See the Vsection on writing GrowZone procedures for a way of reducing the stringency of this rule a little bit. &2 Never use fake pointers or handles.$IA Memory Manager pointer is more than just any old pointer you get using U&variable (or @variable in Pascal). Simil
andle is more than just any old