The <alloc.h> header file


  
This header file contains the following functions:
alloca              calloc              free                FreeHandles
HeapAlloc           HeapAllocESTACK     HeapAllocHigh       HeapAllocHighThrow
HeapAllocThrow      HeapAllocPtr        HeapAvail           HeapCompress
HeapDeref           HeapEnd             HeapFree            HeapFreePtr
HeapFreeIndir       HeapGetHandle       HeapGetLock         HeapLock
HeapMax             HeapMoveHigh        HeapPtrToHandle     HeapRealloc
HeapSize            HeapUnlock          HLock               malloc
realloc
and the following constants and predefined types:
Bool                H_NULL              HANDLE              NULL
size_t

Functions


void *malloc (unsigned long Size);

Allocates a memory block.

malloc allocates a block of Size bytes from the memory heap. It allows a program to allocate memory explicitly as it's needed, and in the exact amounts needed. The heap is used for dynamic allocation of variable-sized blocks of memory. Many data structures, such as trees and lists, naturally employ heap memory allocation. On success, malloc returns a pointer to the newly allocated block of memory. If not enough space exists for the new block, it returns NULL. The contents of the block are left unchanged. If the argument Size is zero malloc also returns NULL. malloc is in fact an ANSI C alias for a TIOS routine originally called HeapAllocPtr (see description of it for more system info).

NOTE: As the TIOS memory manager assigns a handle to each allocated block, and as the total number of handles is limited, malloc is not good for algorithms where you need to allocate a large number of small blocks (as in implementations of linked lists which are usually seen in various C language books and tutorials). The same is true for all other TIOS memory management routines.

void *calloc (unsigned short NoOfItems, unsigned short SizeOfItems);

Allocates a memory block for a given number of items.

calloc allocates a block of NoOfItems x SizeOfItems bytes from the memory heap. On success, calloc returns a pointer to the newly allocated block of memory. If not enough space exists for the new block, it returns NULL. The allocated block will be cleared to zero content.

NOTE: In releases of TIGCCLIB prior to 2.0, calloc was implemented here as a macro, Now, it is a function. It first calls malloc with NoOfItems x SizeOfItems as the argument, then calls memset if the first call was successful.

void *realloc (void *Ptr, unsigned long NewSize);

Reallocates allocated memory.

realloc attempts to shrink or expand the previously allocated block to NewSize bytes. The Ptr argument points to a memory block previously obtained by calling malloc, calloc, or realloc. In opposite to ANSI C implementation, Ptr should not be NULL (anyway, nobody calls realloc with NULL as the argument: ANSI C proposes that realloc should work just like malloc in this case).

realloc adjusts the size of the allocated block to size, copying the contents to a new location if necessary (note that the block will not stay in the high memory after the reallocation, but it will still remain locked; see other functions from this header file for more info). realloc returns the address of the reallocated block, which can be different than the address of the original block. If the block cannot be reallocated, realloc returns NULL.

NOTE: realloc is introduced to increase compatibility with ANSI C. It is better to use TIOS official function HeapRealloc which uses system of handles to memory blocks.

void free (void *Ptr);

Frees allocated blocks.

free deallocates a memory block allocated by a previous call to malloc or calloc.

NOTE: free is in fact an ANSI C alias for a TIOS routine originally called HeapFreePtr.

void *alloca (unsigned long Size);

Allocates memory on a local storage space.

alloca is function which is not included in ANSI C standard, but it exists in many C dialects (including TIGCC). It allocates a block of Size bytes on the CPU stack (local storage space), in opposite to malloc which allocates memory on the memory heap. The space allocated with alloca exists until the containing function returns (i.e. it will be automatically deallocated at the end of the function). Be aware of the fact that the size of the hardware stack on TI calculators is limited to 16 kilobytes, so do not use alloca for allocating large blocks.

alloca is usually used for simulating automatic variable-sized one-dimensional arrays, which will be automatically deallocated when the function ends (like all automatic variables), so it is sometimes more preferable than malloc. For example, to simulate
int a[n];
where 'n' is not known in advance, you can use
int *a = alloca (n);
Note, however, that GNU C extensions allows variable-length arrays, which are more elegant than usage of alloca, and which may also be with more than one dimension (which is not possible with alloca).

NOTE: alloca is a builtin (open-coded) function in GNU C, which is translated to a single instruction which simply adjust the stack. Some compiler command options (like '-ansi') prevent alloca to be an open-codes function. In this implementation of TIGCC, you can not use alloca with such options (however, it is very unlikely that you will ever have such problems).

HANDLE HeapAlloc (unsigned long Size);

Allocates memory and returns a handle of allocated block.

HeapAlloc allocates a block of heap memory of the Size bytes (all odd sizes are rounded up to be even) and returns its handle. Allocated blocks are kept in a single-linked list of blocks. Returns H_NULL if there is not enough memory. The maximum size of a single block is 65520 bytes, and the minimum size is 8 bytes. Use HeapDeref to dereference the handle and get a pointer to the actual memory. Note that an unlocked pointer to the heap is valid only as long as heap compression (i.e. garbage collection) is not done. This routine may cause garbage collection.

HANDLE HeapAllocHigh (unsigned long Size);

Allocates memory at the high end of the heap and returns a handle of allocated block.

HeapAllocHigh allocate a block of Size bytes of heap memory at the high end of the heap, lock it, and return its handle. Returns H_NULL if there is not enough memory. The primary use of this routine is to allocate task local storage. It also compresses the heap first to (hopefully) move all used (unlocked) blocks of memory down. This routine will cause garbage collection. See also HeapAlloc.

NOTE: Blocks of memory that are locked for long periods of time should be moved high in memory so that they do not interfere as much with rest of the system. This routine ALWAYS compresses the heap before it tries to allocate the requested memory and so is much slower than the standard HeapAlloc routine. Locking memory may cause the system to run out of useable memory sooner than if memory is kept unlocked.

void *HeapAllocPtr (unsigned long Size);

Allocates memory at the high end of the heap and returns a pointer to the allocated block.

HeapAllocPtr performs HeapAllocHigh, but instead of the handle, it returns a pointer to the allocated block (NULL in a case of error). It also gives a necessary information to the heap manager which is needed later for deallocating the memory using HeapFreePtr command. This routine is principally equivalent to ANSI C malloc function, so it is aliased here also as malloc.

NOTE: If somebody is interested for it, the handle of the allocated block is stored two bytes below the address returned by HeapAllocPtr.

HANDLE HeapAllocThrow (unsigned long Size);

Performs HeapAlloc, and throws an error if not successful.

HeapAllocThrow calls HeapAlloc and throws a memory error if there is not enough memory. Otherwise, it returns the handle of allocated block.

HANDLE HeapAllocHighThrow (unsigned long Size);

Performs HeapAllocHigh, and throws an error if not successful.

HeapAllocHighThrow calls HeapAllocHigh and throw a memory error if there is not enough memory. Otherwise, it returns the handle of allocated block.

void *HeapDeref (HANDLE Handle);

Dereferences a handle.

HeapDeref dereferences Handle and returns a pointer to the actual block of the memory defined by that Handle. Nearly all heap allocation routines return a "handle" which is an identifier for a block of memory allocated in the heap. In order to use that memory, the handle must be dereferenced. Once a handle is dereferenced, that pointer is valid as long as nothing else is done to cause the heap to be compressed. If the heap is compressed the handle can be redereferenced to make it valid again. If a handle is locked, then the pointer that references that block of memory is valid even after the heap is compressed (since locking a handle means the heap manager will never move the memory associated with that handle).

NOTE: HeapDeref returns a garbage if Handle is H_NULL.

short FreeHandles (void);

Determines number of free handles.

FreeHandles returns a number of free handles.

unsigned long HeapAvail (void);

Determines size of the heap.

HeapAvail returns the total amount of free bytes in the heap (the sum of all of the individual blocks of memory).

void HeapCompress (void);

Compress the heap.

HeapCompress coalesces all used heap blocks, deleting any free blocks from the heap if possible. If there are any locked blocks, the heap may remain fragmented. This routine is called automatically by the system whenever it is needed and usually should not be called by applications.

void HeapFree (HANDLE Handle);

Free a heap block given its handle.

HeapFree frees a heap block associated with handle Handle.

void HeapFreeIndir (void *PtrHandle);

Free a heap block given a pointer to it.

HeapFreeIndir is like HeapFree except you pass the address of a variable which keeps the block handle instead of the handle itself. If the handle that PtrHandle points to is not H_NULL, then frees that handle and sets the handle variable that is pointed to by PtrHandle to H_NULL.

Maybe this sounds a bit confuse to you. In fact, doing
HeapFreeIndir (&handle);    // The ampersand ('&') is important
works exactly the same as
if (handle) HeapFree (handle);
handle = H_NULL;
NOTE: In releases of TIGCCLIB prior to 2.2, the information about this routine was quite misleading or even wrong.

void HeapFreePtr (void *Ptr);

Frees a block allocated using HeapAllocPtr.

HeapFreePtr frees a heap block pointed to by Ptr. The block must be a block which is allocated using HeapAllocPtr command.

short HeapGetLock (HANDLE Handle);

Determines whether a block is locked.

Returns non-zero if the block given by Handle is locked, 0 if it is not (i.e. if that memory is free to move on the next heap compression).

HANDLE HeapLock (HANDLE Handle);

Locks a block.

HeapLock locks the block referenced by Handle so that it is not moved during garbage collection. Returns Handle if OK, else returns H_NULL.

NOTE: Locking memory may cause the system to run out of useable memory sooner than if memory is kept unlocked.

unsigned long HeapMax (void);

Determines maximum allocatable block.

HeapMax returns the maximum block allocatable on the heap (it will be in range 0..65520). Note that this may not equal to HeapAvail due to locked blocks, overhead, and maximum block size. This routine will (always) cause garbage collection.

HANDLE HeapMoveHigh (HANDLE Handle);

Reallocates a block.

HeapMoveHigh tries to reallocate a block referenced by Handle as high in memory as possible. The block must not be locked. If successful, returns the handle passed; otherwise returns H_NULL (in this case, the block is still in the same place as before, so no memory is lost). This routine will cause heap compression (garbage collection).

HANDLE HeapRealloc (HANDLE Handle, unsigned long NewSize);

Reallocates a block to a new size.

If Handle is H_NULL, HeapRealloc calls HeapAlloc. Otherwise, it tries to reallocate the given heap block to a new size. Returns H_NULL if there is not enough memory (it will try to call HeapCompress) or if new size is invalid; otherwise returns Handle. If the heap-block is locked, then the block will not be moved in order to reallocate it. However, unlocked blocks above the heap-block will be moved. The contents of the object will be unchanged up to the lesser of the new and old size. If the new size is larger the value of the newly allocated portion of the object is indeterminate. This routine may cause garbage collection.

unsigned short HeapSize (HANDLE Handle);

Determines the size of an allocated block.

HeapSize returns the number of bytes allocated for the heap block referenced by Handle. Due to word alignment and minimum block size, this may not be the amount it was allocated with. Also note that because of locked blocks, it is possible (rare) that a heap block will actually be bumped up a few words by the HeapCompress routine. So never assume that the value returned by HeapSize is the true number of bytes used by the data stored in the heap block.

HANDLE HeapUnlock (HANDLE Handle);

Unlocks a block.

HeapUnlock unlock the block referenced by the Handle so that it can be moved during garbage collection. Returns Handle if OK, else returns H_NULL.

void *HLock (HANDLE Handle);

Locks and dereferences a handle.

HLock locks a block referenced by Handle so that it will not move on the next heap compression, and returns a pointer to the actual memory block. Returns NULL in a case of error.

NOTE: Locking memory may cause the system to run out of useable memory sooner than if memory is kept unlocked.

HANDLE HeapPtrToHandle (void *Ptr);

Determines a handle associated with block.

HeapPtrToHandle returns a handle which is associated to a block which is pointed to by Ptr (or H_NULL if there is no any handle which references to given block). This routine works by searching the entire table of handles for the given pointer, and so should be used accordingly. It assumes that the heap has not been compressed since the dereferenced pointer was originally obtained or the block it points to is locked.

HANDLE HeapGetHandle (void);

Gets a next available handle.

HeapGetHandle returns a number of first unallocated (free) handle, or H_NULL if there is no free handles. Used mainly for internal purposes.

void *HeapEnd (void);

Determines the end of the heap.

HeapEnd returns the pointer to the end of the heap.

HANDLE HeapAllocESTACK (unsigned long Size);

HeapAllocESTACK works like HeapAlloc, but performs reducing the size of the expressions stack if necessary (i.e. if there is no enough memory). Returns NULL if there is not enough memory even after reducing the size of the expressions stack.

NOTE: The information about this routine in releases of TIGCCLIB prior to 2.0 were wrong!


Constants and predefined types


enum Bool

Bool is enumerated type for describing true or false values. It is defined as

enum Bool {FALSE, TRUE};

type size_t

size_t is a type proposed in ANSI C for defining size of strings and memory blocks. It is defined here as

typedef unsigned long size_t;

const NULL

NULL is a null-pointer value, defined as (void *) 0.

type HANDLE

HANDLE is a type which represents handles associated to allocated memory blocks. It is defined as

typedef unsigned short HANDLE;

const H_NULL

H_NULL is a null-handle defined as a constant with value 0.

Return to the main index