A pointer to the desired type is created. Array elements are accessed from this pointer as normal. Other operations depend on macros which extract the stored type from the type of the pointer.
The array is managed with a header, which is positioned before the beginning of the array. The malloc'ed memory area starts at the beginning of this header. However the pointer to the header is not stored, but rather derived from the array pointer whenever it is required.
Arrays have a size and a capacity. The size is the number of elements in use, and the capacity is the number of elements available before a new memory allocation is required. When new memory is required, an excess is reqested to allow the array to grow further before performing another malloc.
If the precise amount of memory is known, the capacity can be controlled directly using the 'reserve' macro.
Example: to handle an array of type mytype:
int i; mytype x,y; mytype *array; ccp4array_new(array); ccp4array_append_n(array, x, 3); for ( i = 0; i < 3; i++ ) y = array[i]; ccp4array_free(array);