WCSLIB: Memory management

WCSLIB 7.4

Memory management

The initialization routines for certain of the WCSLIB data structures allocate memory for some of their members:

- wcsinit() optionally allocates memory for the crpix, pc, cdelt, crval, cunit, ctype, pv, ps, cd, crota, colax, cname, crder, and csyer arrays in the wcsprm struct (using lininit() for certain of these). Note that wcsinit() does not allocate memory for the tab array - refer to the usage notes for wcstab() in wcshdr.h. If the pc matrix is not unity, wcsset() (via linset()) also allocates memory for the piximg and imgpix arrays.
- lininit(): optionally allocates memory for the crpix, pc, and cdelt arrays in the linprm struct. If the pc matrix is not unity, linset() also allocates memory for the piximg and imgpix arrays. Typically these would be used by wcsinit() and wcsset().
- tabini(): optionally allocates memory for the K, map, crval, index, and coord arrays (including the arrays referenced by index[]) in the tabprm struct. tabmem() takes control of any of these arrays that may have been allocated by the user, specifically in that tabfree() will then free it. tabset() also allocates memory for the sense, p0, delta and extrema arrays.
- disinit(): optionally allocates memory for the dtype, dp, and maxdis arrays. disset() also allocates memory for a number of arrays that hold distortion parmeters and intermediate values: axmap, Nhat, offset, scale, iparm, and dparm, and also several private work arrays: disp2x, disx2p, and tmpmem.

The caller may load data into these arrays but must not modify the struct members (i.e. the pointers) themselves or else memory leaks will result.

wcsinit() maintains a record of memory it has allocated and this is used by wcsfree() which wcsinit() uses to free any memory that it may have allocated on a previous invokation. Thus it is not necessary for the caller to invoke wcsfree() separately if wcsinit() is invoked repeatedly on the same wcsprm struct. Likewise, wcsset() deallocates memory that it may have allocated on a previous invokation. The same comments apply to lininit(), linfree(), and linset(), to tabini(), tabfree(), and tabset(), and to disinit(), disfree() and disset().

A memory leak will result if a wcsprm, linprm, tabprm, or disprm struct goes out of scope before the memory has been free'd, either by the relevant routine, wcsfree(), linfree(), tabfree(), or disfree() or otherwise. Likewise, if one of these structs itself has been malloc'd and the allocated memory is not free'd when the memory for the struct is free'd. A leak may also arise if the caller interferes with the array pointers in the "private" part of these structs.

Beware of making a shallow copy of a wcsprm, linprm, tabprm, or disprm struct by assignment; any changes made to allocated memory in one would be reflected in the other, and if the memory allocated for one was free'd the other would reference unallocated memory. Use the relevant routine instead to make a deep copy: wcssub(), lincpy(), tabcpy(), or discpy().