LCOV - code coverage report
Current view: top level - gl - xalloc.h (source / functions) Hit Total Coverage
Test: GNU SASL Lines: 0 13 0.0 %
Date: 2012-05-28 Functions: 0 2 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 6 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* xalloc.h -- malloc with out-of-memory checking
       2                 :            : 
       3                 :            :    Copyright (C) 1990-2000, 2003-2004, 2006-2012 Free Software Foundation, Inc.
       4                 :            : 
       5                 :            :    This program is free software: you can redistribute it and/or modify
       6                 :            :    it under the terms of the GNU General Public License as published by
       7                 :            :    the Free Software Foundation; either version 3 of the License, or
       8                 :            :    (at your option) any later version.
       9                 :            : 
      10                 :            :    This program is distributed in the hope that it will be useful,
      11                 :            :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      12                 :            :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      13                 :            :    GNU General Public License for more details.
      14                 :            : 
      15                 :            :    You should have received a copy of the GNU General Public License
      16                 :            :    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
      17                 :            : 
      18                 :            : #ifndef XALLOC_H_
      19                 :            : # define XALLOC_H_
      20                 :            : 
      21                 :            : # include <stddef.h>
      22                 :            : 
      23                 :            : # include "xalloc-oversized.h"
      24                 :            : 
      25                 :            : # ifdef __cplusplus
      26                 :            : extern "C" {
      27                 :            : # endif
      28                 :            : 
      29                 :            : 
      30                 :            : # if __GNUC__ >= 3
      31                 :            : #  define _GL_ATTRIBUTE_MALLOC __attribute__ ((__malloc__))
      32                 :            : # else
      33                 :            : #  define _GL_ATTRIBUTE_MALLOC
      34                 :            : # endif
      35                 :            : 
      36                 :            : # if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)
      37                 :            : #  define _GL_ATTRIBUTE_ALLOC_SIZE(args) __attribute__ ((__alloc_size__ args))
      38                 :            : # else
      39                 :            : #  define _GL_ATTRIBUTE_ALLOC_SIZE(args)
      40                 :            : # endif
      41                 :            : 
      42                 :            : /* This function is always triggered when memory is exhausted.
      43                 :            :    It must be defined by the application, either explicitly
      44                 :            :    or by using gnulib's xalloc-die module.  This is the
      45                 :            :    function to call when one wants the program to die because of a
      46                 :            :    memory allocation failure.  */
      47                 :            : extern _Noreturn void xalloc_die (void);
      48                 :            : 
      49                 :            : void *xmalloc (size_t s)
      50                 :            :       _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_ALLOC_SIZE ((1));
      51                 :            : void *xzalloc (size_t s)
      52                 :            :       _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_ALLOC_SIZE ((1));
      53                 :            : void *xcalloc (size_t n, size_t s)
      54                 :            :       _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_ALLOC_SIZE ((1, 2));
      55                 :            : void *xrealloc (void *p, size_t s)
      56                 :            :       _GL_ATTRIBUTE_ALLOC_SIZE ((2));
      57                 :            : void *x2realloc (void *p, size_t *pn);
      58                 :            : void *xmemdup (void const *p, size_t s)
      59                 :            :       _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_ALLOC_SIZE ((2));
      60                 :            : char *xstrdup (char const *str)
      61                 :            :       _GL_ATTRIBUTE_MALLOC;
      62                 :            : 
      63                 :            : /* In the following macros, T must be an elementary or structure/union or
      64                 :            :    typedef'ed type, or a pointer to such a type.  To apply one of the
      65                 :            :    following macros to a function pointer or array type, you need to typedef
      66                 :            :    it first and use the typedef name.  */
      67                 :            : 
      68                 :            : /* Allocate an object of type T dynamically, with error checking.  */
      69                 :            : /* extern t *XMALLOC (typename t); */
      70                 :            : # define XMALLOC(t) ((t *) xmalloc (sizeof (t)))
      71                 :            : 
      72                 :            : /* Allocate memory for N elements of type T, with error checking.  */
      73                 :            : /* extern t *XNMALLOC (size_t n, typename t); */
      74                 :            : # define XNMALLOC(n, t) \
      75                 :            :     ((t *) (sizeof (t) == 1 ? xmalloc (n) : xnmalloc (n, sizeof (t))))
      76                 :            : 
      77                 :            : /* Allocate an object of type T dynamically, with error checking,
      78                 :            :    and zero it.  */
      79                 :            : /* extern t *XZALLOC (typename t); */
      80                 :            : # define XZALLOC(t) ((t *) xzalloc (sizeof (t)))
      81                 :            : 
      82                 :            : /* Allocate memory for N elements of type T, with error checking,
      83                 :            :    and zero it.  */
      84                 :            : /* extern t *XCALLOC (size_t n, typename t); */
      85                 :            : # define XCALLOC(n, t) \
      86                 :            :     ((t *) (sizeof (t) == 1 ? xzalloc (n) : xcalloc (n, sizeof (t))))
      87                 :            : 
      88                 :            : 
      89                 :            : # if HAVE_INLINE
      90                 :            : #  define static_inline static inline
      91                 :            : # else
      92                 :            : void *xnmalloc (size_t n, size_t s)
      93                 :            :       _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_ALLOC_SIZE ((1, 2));
      94                 :            : void *xnrealloc (void *p, size_t n, size_t s)
      95                 :            :       _GL_ATTRIBUTE_ALLOC_SIZE ((2, 3));
      96                 :            : void *x2nrealloc (void *p, size_t *pn, size_t s);
      97                 :            : char *xcharalloc (size_t n)
      98                 :            :       _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_ALLOC_SIZE ((1));
      99                 :            : # endif
     100                 :            : 
     101                 :            : # ifdef static_inline
     102                 :            : 
     103                 :            : /* Allocate an array of N objects, each with S bytes of memory,
     104                 :            :    dynamically, with error checking.  S must be nonzero.  */
     105                 :            : 
     106                 :            : static_inline void *xnmalloc (size_t n, size_t s)
     107                 :            :                     _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_ALLOC_SIZE ((1, 2));
     108                 :            : static_inline void *
     109                 :            : xnmalloc (size_t n, size_t s)
     110                 :            : {
     111                 :            :   if (xalloc_oversized (n, s))
     112                 :            :     xalloc_die ();
     113                 :            :   return xmalloc (n * s);
     114                 :            : }
     115                 :            : 
     116                 :            : /* Change the size of an allocated block of memory P to an array of N
     117                 :            :    objects each of S bytes, with error checking.  S must be nonzero.  */
     118                 :            : 
     119                 :            : static_inline void *xnrealloc (void *p, size_t n, size_t s)
     120                 :            :                     _GL_ATTRIBUTE_ALLOC_SIZE ((2, 3));
     121                 :            : static_inline void *
     122                 :            : xnrealloc (void *p, size_t n, size_t s)
     123                 :            : {
     124                 :            :   if (xalloc_oversized (n, s))
     125                 :            :     xalloc_die ();
     126                 :            :   return xrealloc (p, n * s);
     127                 :            : }
     128                 :            : 
     129                 :            : /* If P is null, allocate a block of at least *PN such objects;
     130                 :            :    otherwise, reallocate P so that it contains more than *PN objects
     131                 :            :    each of S bytes.  *PN must be nonzero unless P is null, and S must
     132                 :            :    be nonzero.  Set *PN to the new number of objects, and return the
     133                 :            :    pointer to the new block.  *PN is never set to zero, and the
     134                 :            :    returned pointer is never null.
     135                 :            : 
     136                 :            :    Repeated reallocations are guaranteed to make progress, either by
     137                 :            :    allocating an initial block with a nonzero size, or by allocating a
     138                 :            :    larger block.
     139                 :            : 
     140                 :            :    In the following implementation, nonzero sizes are increased by a
     141                 :            :    factor of approximately 1.5 so that repeated reallocations have
     142                 :            :    O(N) overall cost rather than O(N**2) cost, but the
     143                 :            :    specification for this function does not guarantee that rate.
     144                 :            : 
     145                 :            :    Here is an example of use:
     146                 :            : 
     147                 :            :      int *p = NULL;
     148                 :            :      size_t used = 0;
     149                 :            :      size_t allocated = 0;
     150                 :            : 
     151                 :            :      void
     152                 :            :      append_int (int value)
     153                 :            :        {
     154                 :            :          if (used == allocated)
     155                 :            :            p = x2nrealloc (p, &allocated, sizeof *p);
     156                 :            :          p[used++] = value;
     157                 :            :        }
     158                 :            : 
     159                 :            :    This causes x2nrealloc to allocate a block of some nonzero size the
     160                 :            :    first time it is called.
     161                 :            : 
     162                 :            :    To have finer-grained control over the initial size, set *PN to a
     163                 :            :    nonzero value before calling this function with P == NULL.  For
     164                 :            :    example:
     165                 :            : 
     166                 :            :      int *p = NULL;
     167                 :            :      size_t used = 0;
     168                 :            :      size_t allocated = 0;
     169                 :            :      size_t allocated1 = 1000;
     170                 :            : 
     171                 :            :      void
     172                 :            :      append_int (int value)
     173                 :            :        {
     174                 :            :          if (used == allocated)
     175                 :            :            {
     176                 :            :              p = x2nrealloc (p, &allocated1, sizeof *p);
     177                 :            :              allocated = allocated1;
     178                 :            :            }
     179                 :            :          p[used++] = value;
     180                 :            :        }
     181                 :            : 
     182                 :            :    */
     183                 :            : 
     184                 :            : static_inline void *
     185                 :          0 : x2nrealloc (void *p, size_t *pn, size_t s)
     186                 :            : {
     187                 :          0 :   size_t n = *pn;
     188                 :            : 
     189         [ #  # ]:          0 :   if (! p)
     190                 :            :     {
     191         [ #  # ]:          0 :       if (! n)
     192                 :            :         {
     193                 :            :           /* The approximate size to use for initial small allocation
     194                 :            :              requests, when the invoking code specifies an old size of
     195                 :            :              zero.  This is the largest "small" request for the GNU C
     196                 :            :              library malloc.  */
     197                 :            :           enum { DEFAULT_MXFAST = 64 * sizeof (size_t) / 4 };
     198                 :            : 
     199                 :          0 :           n = DEFAULT_MXFAST / s;
     200                 :          0 :           n += !n;
     201                 :            :         }
     202                 :            :     }
     203                 :            :   else
     204                 :            :     {
     205                 :            :       /* Set N = ceil (1.5 * N) so that progress is made if N == 1.
     206                 :            :          Check for overflow, so that N * S stays in size_t range.
     207                 :            :          The check is slightly conservative, but an exact check isn't
     208                 :            :          worth the trouble.  */
     209         [ #  # ]:          0 :       if ((size_t) -1 / 3 * 2 / s <= n)
     210                 :          0 :         xalloc_die ();
     211                 :          0 :       n += (n + 1) / 2;
     212                 :            :     }
     213                 :            : 
     214                 :          0 :   *pn = n;
     215                 :          0 :   return xrealloc (p, n * s);
     216                 :            : }
     217                 :            : 
     218                 :            : /* Return a pointer to a new buffer of N bytes.  This is like xmalloc,
     219                 :            :    except it returns char *.  */
     220                 :            : 
     221                 :            : static_inline char *xcharalloc (size_t n)
     222                 :            :                     _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_ALLOC_SIZE ((1));
     223                 :            : static_inline char *
     224                 :          0 : xcharalloc (size_t n)
     225                 :            : {
     226                 :          0 :   return XNMALLOC (n, char);
     227                 :            : }
     228                 :            : 
     229                 :            : # endif
     230                 :            : 
     231                 :            : # ifdef __cplusplus
     232                 :            : }
     233                 :            : 
     234                 :            : /* C++ does not allow conversions from void * to other pointer types
     235                 :            :    without a cast.  Use templates to work around the problem when
     236                 :            :    possible.  */
     237                 :            : 
     238                 :            : template <typename T> inline T *
     239                 :            : xrealloc (T *p, size_t s)
     240                 :            : {
     241                 :            :   return (T *) xrealloc ((void *) p, s);
     242                 :            : }
     243                 :            : 
     244                 :            : template <typename T> inline T *
     245                 :            : xnrealloc (T *p, size_t n, size_t s)
     246                 :            : {
     247                 :            :   return (T *) xnrealloc ((void *) p, n, s);
     248                 :            : }
     249                 :            : 
     250                 :            : template <typename T> inline T *
     251                 :            : x2realloc (T *p, size_t *pn)
     252                 :            : {
     253                 :            :   return (T *) x2realloc ((void *) p, pn);
     254                 :            : }
     255                 :            : 
     256                 :            : template <typename T> inline T *
     257                 :            : x2nrealloc (T *p, size_t *pn, size_t s)
     258                 :            : {
     259                 :            :   return (T *) x2nrealloc ((void *) p, pn, s);
     260                 :            : }
     261                 :            : 
     262                 :            : template <typename T> inline T *
     263                 :            : xmemdup (T const *p, size_t s)
     264                 :            : {
     265                 :            :   return (T *) xmemdup ((void const *) p, s);
     266                 :            : }
     267                 :            : 
     268                 :            : # endif
     269                 :            : 
     270                 :            : 
     271                 :            : #endif /* !XALLOC_H_ */

Generated by: LCOV version 1.9