NewHandle
NewHandle Allocate relocatable block from current heap zone
#include <Memory.h> Memory Manager
Handle NewHandle(dataSize );
Size dataSize ; desired size for the data (a 32-bit value)
returns handle leading to allocated area; NIL if can't
NewHandle is the generic memory allocation tool for obtaining blocks of
relocatable memory.
dataSize is the desired size for the allocated data area. The allocated block
actually occupies up to 12 bytes more than dataSize .
Returns: a generic Handle (a pointer to a pointer to a data area; officially,
Handle is a typedef for char **). If the area cannot be allocated,
the return value is NIL (0).

Notes: NewHandle makes every effort to allocate the requested memory,
including compacting the heap, increasing its size, purging purgeable
blocks, and calling its grow function, if any (see SetGrowZone).
Initially, all allocated handles are unlocked (moveable) and un purgeable.
Use HLock and HPurge to change these initial settings.
The returned Handle is a pointer to a "master pointer" (which actually
points to the data area). Should the block be moved, the value of the Handle
remains the same, but its master pointer will change.
All Macintosh Handle values are instances of double in direction. To access
the area allocated by this call, you can "de reference" the handle. For
instance:
Handle myHandle;
char *myDataPtr, c;
myHandle = NewHandle( 1024 ); /* allocate 1K bytes */
myDataPtr = * myHandle; [TOKEN:12074] de reference: get addr of data */
*myDataPtr = 1; [TOKEN:12074] store a value */
c = myDataPtr[900]; [TOKEN:12074] read a value */
For allocating an instance of a structure, you will need to coerce the
returned value into the desired data type. Then, there are several ways to
access the data, e.g.:
typedef MyStruct **StructHandle;
struct MyStruct *myStructPtr;
StructHandle myHandle;
myHandle = (StructHandle)NewHandle( sizeof (MyStruct) );
x = (* myHandle)->myField; /* is the same as ... */
x = (** myHandle).myField;
myStructPtr = * myHandle; /* dereference (get addr of data) */
x = myStructPtr->myField; /* is the same as ... */
x = (*myDataPtr).myField;
Locking Handles
Many Toolbox and OS calls can cause a relocatable block to be moved (as
well as calls to functions in unloaded segments), thus, you should NEVER
rely on a de referenced pointer to remain valid for any length of time. For
any extensive access, you must lock a handle:
HLock( myHandle ); [TOKEN:12074] keep it from moving */
.
... access the data ...
.
HUnlock( myHandle ); [TOKEN:12074] let it move freely */
Use DisposHandle to free up the allocated block. You can shrink or
expand the allocation via SetHandleSize. You should unlock the handle
before calling SetHandleSize. See About the Moves Memory Icon for
more on determining when memory may move.
You can allocate non-relocatable data areas with NewPtr. However, this
can cause the heap to become fragmented, making it impossible to get the
maximum useable storage from available RAM.
The NewEmptyHandle function creates an empty Handle; that is, it
returns the address of a NIL master pointer, without actually allocating any
memory.