/*! * \file lib/gis/alloc.c * * \brief GIS Library - Memory allocation routines. * * (C) 2001-2009 by the GRASS Development Team * * This program is free software under the GNU General Public License * (>=v2). Read the file COPYING that comes with GRASS for details. * * \author Original author CERL */ #include #include #include /*! * \brief Memory allocation. * * Allocates a block of memory at least n bytes which is * aligned properly for all data types. A pointer to the aligned block * is returned. * * Dies with error message on memory allocation fail. * * \param file file name * \param line line number * \param t number of elements */ void *G__malloc(const char *file, int line, size_t n) { void *buf; if (n <= 0) n = 1; /* make sure we get a valid request */ buf = malloc(n); if (!buf) { struct Cell_head window; G_get_window(&window); G_important_message(_("Current region rows: %d, cols: %d"), window.rows, window.cols); G_fatal_error(_("G_malloc: unable to allocate %lu bytes of memory at %s:%d"), (unsigned long) n, file, line); } return buf; } /*! * \brief Memory allocation. * * Allocates a properly aligned block of memory n*m * bytes in length, initializes the allocated memory to zero, and * returns a pointer to the allocated block of memory. * * Dies with error message on memory allocation fail. * * Note: Allocating memory for reading and writing raster maps * is discussed in \ref Allocating_Raster_I_O_Buffers. * * \param file fine name * \param line line number * \param m element size * \param n number of elements */ void *G__calloc(const char *file, int line, size_t m, size_t n) { void *buf; if (m <= 0) m = 1; /* make sure we get a valid requests */ if (n <= 0) n = 1; buf = calloc(m, n); if (!buf) { struct Cell_head window; G_get_window(&window); G_important_message(_("Current region rows: %d, cols: %d"), window.rows, window.cols); G_fatal_error(_("G_calloc: unable to allocate %lu * %lu bytes of memory at %s:%d"), (unsigned long) m, (unsigned long) n, file, line); } return buf; } /*! * \brief Memory reallocation. * * Changes the size of a previously allocated block of memory * at ptr and returns a pointer to the new block of memory. The * size may be larger or smaller than the original size. If the * original block cannot be extended "in place", then a new block is * allocated and the original block copied to the new block. * * Note: If buf is NULL, then this routine simply * allocates a block of n bytes else buf must point to * memory that has been dynamically allocated by G_malloc(), * G_calloc(), G_realloc(), malloc(3), alloc(3), or realloc(3).. This * routine works around broken realloc() routines, which do not * handle a NULL buf. * * \param file file name * \param line line number * \param[in,out] buf buffer holding original data * \param[in] n array size */ void *G__realloc(const char *file, int line, void *buf, size_t n) { if (n <= 0) n = 1; /* make sure we get a valid request */ if (!buf) buf = malloc(n); else buf = realloc(buf, n); if (!buf) { struct Cell_head window; G_get_window(&window); G_important_message(_("Current region rows: %d, cols: %d"), window.rows, window.cols); G_fatal_error(_("G_realloc: unable to allocate %lu bytes of memory at %s:%d"), (unsigned long) n, file, line); } return buf; } /*! * \brief Free allocated memory. * * \param[in,out] buf buffer holding original data */ void G_free(void *buf) { free(buf); } /*! * \brief Advance void pointer * * Advances void pointer by size bytes. Returns new pointer * value. * * Useful in raster row processing loops, substitutes * \code CELL *cell; cell += n; \endcode * * Now \code rast = G_incr_void_ptr(rast, Rast_cell_size(data_type)) \endcode * * (where rast is void* and data_type is RASTER_MAP_TYPE can be * used instead of rast++.) * * Very useful to generalize the row processing - loop i.e. * \code * void * buf_ptr += Rast_cell_size(data_type) * \endcode * * \param ptr pointer * \param size buffer size * * \return pointer to the data */ #ifndef G_incr_void_ptr void *G_incr_void_ptr(const void *ptr, size_t size) { /* assuming that the size of unsigned char is 1 */ return (void *)((const unsigned char *)ptr + size); } #endif