2 * This file is part of DisOrder.
3 * Copyright (C) 2004, 2005, 2006, 2007 Richard Kettlewell
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 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
21 * @brief Memory management
37 /** @brief Allocate and zero out
38 * @param n Number of bytes to allocate
39 * @return Pointer to allocated memory, or 0
41 static void *malloc_and_zero(size_t n
) {
42 void *ptr
= malloc(n
);
44 if(ptr
) memset(ptr
, 0, n
);
49 static void *(*do_malloc
)(size_t) = GC_malloc
;
50 static void *(*do_realloc
)(void *, size_t) = GC_realloc
;
51 static void *(*do_malloc_atomic
)(size_t) = GC_malloc_atomic
;
52 static void (*do_free
)(void *) = GC_free
;
54 static void *(*do_malloc
)(size_t) = malloc_and_zero
;
55 static void *(*do_realloc
)(void *, size_t) = realloc
;
56 static void *(*do_malloc_atomic
)(size_t) = malloc
;
57 static void (*do_free
)(void *) = free
;
60 /** @brief Initialize memory management
62 * Must be called by all programs that use garbage collection. Define
63 * @c ${DISORDER_GC} to @c no to suppress use of the collector
64 * (e.g. for debugging purposes).
70 if(((e
= getenv("DISORDER_GC")) && !strcmp(e
, "no"))) {
71 do_malloc
= malloc_and_zero
;
72 do_malloc_atomic
= malloc
;
77 assert(GC_all_interior_pointers
);
82 /** @brief Allocate memory
83 * @param n Bytes to allocate
84 * @return Pointer to allocated memory
86 * Terminates the process on error. The allocated memory is always
89 void *xmalloc(size_t n
) {
92 if(!(ptr
= do_malloc(n
)) && n
)
93 fatal(errno
, "error allocating memory");
97 /** @brief Reallocate memory
98 * @param ptr Block to reallocated
99 * @param n Bytes to allocate
100 * @return Pointer to allocated memory
102 * Terminates the process on error. It is NOT guaranteed that any
103 * additional memory allocated is 0-filled.
105 void *xrealloc(void *ptr
, size_t n
) {
106 if(!(ptr
= do_realloc(ptr
, n
)) && n
)
107 fatal(errno
, "error allocating memory");
111 /** @brief Allocate memory
112 * @param count Number of objects to allocate
113 * @param size Size of one object
114 * @return Pointer to allocated memory
116 * Terminates the process on error. The allocated memory is always
119 void *xcalloc(size_t count
, size_t size
) {
120 if(count
> SIZE_MAX
/ size
)
121 fatal(0, "excessively large calloc");
122 return xmalloc(count
* size
);
125 /** @brief Allocate memory
126 * @param n Bytes to allocate
127 * @return Pointer to allocated memory
129 * Terminates the process on error. The allocated memory is not
130 * guaranteed to be 0-filled and is not suitable for storing pointers
133 void *xmalloc_noptr(size_t n
) {
136 if(!(ptr
= do_malloc_atomic(n
)) && n
)
137 fatal(errno
, "error allocating memory");
141 /** @brief Reallocate memory
142 * @param ptr Block to reallocated
143 * @param n Bytes to allocate
144 * @return Pointer to allocated memory
146 * Terminates the processf on error. It is NOT guaranteed that any
147 * additional memory allocated is 0-filled. The block must have been
148 * allocated with xmalloc_noptr() (or xrealloc_noptr()) initially.
150 void *xrealloc_noptr(void *ptr
, size_t n
) {
152 return xmalloc_noptr(n
);
153 if(!(ptr
= do_realloc(ptr
, n
)) && n
)
154 fatal(errno
, "error allocating memory");
158 /** @brief Duplicate a string
159 * @param s String to copy
160 * @return New copy of string
162 * This uses the equivalent of xmalloc_noptr() to allocate the new string.
164 char *xstrdup(const char *s
) {
167 if(!(t
= do_malloc_atomic(strlen(s
) + 1)))
168 fatal(errno
, "error allocating memory");
172 /** @brief Duplicate a prefix of a string
173 * @param s String to copy
174 * @param n Prefix of string to copy
175 * @return New copy of string
177 * This uses the equivalent of xmalloc_noptr() to allocate the new string.
178 * @p n must not exceed the length of the string.
180 char *xstrndup(const char *s
, size_t n
) {
183 if(!(t
= do_malloc_atomic(n
+ 1)))
184 fatal(errno
, "error allocating memory");
190 /** @brief Free memory
191 * @param ptr Block to free or 0
193 void xfree(void *ptr
) {