Using the Local Heap

The local heap contains free memory that may be allocated for private use by the application. The local heap is located in the application's data segment and is therefore accessible only to a specific instance of the application. You can allocate memory from the local heap in blocks of up to 64K and the memory can be fixed, movable, or discardable, as needed.

Windows does not automatically supply an application with a local heap. To request a local heap for your application, use the HEAPSIZE statement in the application's module-definition file. This statement sets the initial size, in bytes, of the local heap. If the local heap is in a fixed data segment, you may allocate up to the specified heap size. If the local heap is in a movable data segment, you may allocate beyond the initial heap size and up to 64K, since Windows will automatically allocate additional space for the local heap until the data segment reaches the 64K maximum. You should note, however, that if Windows allocates additional local memory to satisfy a local allocation, it may move the data segment, making invalid any long pointers to blocks in local memory.

The maximum size of any local heap depends on the size of the application's stack, static data, and global data. The local heap shares the data segment with the stack and this data. Since a data segment can be no larger than 64K, an application's local heap can be no larger than 64K minus the size of the application's stack, global data, and static data. The application's stack size is defined by the STACKSIZE statement in the application's module-definition file or by the equivalent linker option. The global and static data size depends on how many strings and global or static variables are declared in the application. Windows enforces a minimum stack size of 5K; if the module-definition file specifies a smaller stack size, Windows sets the stack size to 5K.

You can allocate local memory by using the LocalAlloc function. The function allocates a block of memory in the application's local heap and returns a handle to the memory. You lock the local memory block by using the LocalLock function. This returns a near address (a 16-bit offset) to the first byte in the memory block. The offset is relative to the beginning of your data segment. In the following example, the LocalAlloc function allocates 256 bytes of movable memory and the LocalLock function locks it so that the first 256 bytes can be set to 0xFF:

HANDLE hMem;

PSTR pMem;

int i;

if ((hMem = LocalAlloc(LMEM_MOVEABLE, 256)) != NULL) {

if ((pMem = LocalLock(hMem)) != NULL) {

for (i = 0; i < 256; i++)

pMem[i] = 0xFF;

LocalUnlock(hMem);

}

}

In this example, the application unlocks the memory handle by using the LocalUnlock function immediately after accessing the memory block. Once a movable or discardable memory block is locked, Windows guarantees that the block will remain fixed in memory until it is unlocked. This means the address remains valid as long as the block remains locked, but this also keeps Windows from making the best use of memory if other allocation requests are made. If you want to ensure that you are getting the best performance from your application's local heap, make sure you unlock memory after using it.

The LocalAlloc returns NULL if an allocation request fails. You should always check the return value to ensure that a valid handle exists. If desired, you can check to see how much memory is available in the local heap by using the LocalCompact function. This function returns the number of bytes in the largest contiguous free block of memory in the local heap.

You should also check the address returned by the LocalLock function. This function returns NULL if the memory handle was not valid or if the contents of the memory block have been discarded.