diff options
author | Christian Grothoff <christian@grothoff.org> | 2009-05-29 00:46:26 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2009-05-29 00:46:26 +0000 |
commit | 0a217a8df1657b4334b55b0e4a6c7837a8dbcfd9 (patch) | |
tree | 6b552f40eb089db96409a312a98d9b12bd669102 /src/util/common_allocation.c | |
download | gnunet-0a217a8df1657b4334b55b0e4a6c7837a8dbcfd9.tar.gz gnunet-0a217a8df1657b4334b55b0e4a6c7837a8dbcfd9.zip |
ng
Diffstat (limited to 'src/util/common_allocation.c')
-rw-r--r-- | src/util/common_allocation.c | 206 |
1 files changed, 206 insertions, 0 deletions
diff --git a/src/util/common_allocation.c b/src/util/common_allocation.c new file mode 100644 index 000000000..9fabb3a32 --- /dev/null +++ b/src/util/common_allocation.c | |||
@@ -0,0 +1,206 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | (C) 2001, 2002, 2003, 2005, 2006 Christian Grothoff (and other contributing authors) | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 2, or (at your | ||
8 | option) any later version. | ||
9 | |||
10 | GNUnet 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. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 59 Temple Place - Suite 330, | ||
18 | Boston, MA 02111-1307, USA. | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @file util/memory/common_allocation.c | ||
23 | * @brief wrapper around malloc/free | ||
24 | * @author Christian Grothoff | ||
25 | */ | ||
26 | |||
27 | #include "platform.h" | ||
28 | #include "gnunet_common.h" | ||
29 | |||
30 | #ifndef INT_MAX | ||
31 | #define INT_MAX 0x7FFFFFFF | ||
32 | #endif | ||
33 | |||
34 | /** | ||
35 | * Allocate memory. Checks the return value, aborts if no more | ||
36 | * memory is available. | ||
37 | * | ||
38 | * @param size how many bytes of memory to allocate, do NOT use | ||
39 | * this function (or GNUNET_malloc) to allocate more than several MB | ||
40 | * of memory, if you are possibly needing a very large chunk use | ||
41 | * GNUNET_xmalloc_unchecked_ instead. | ||
42 | * @param filename where in the code was the call to GNUNET_array_grow | ||
43 | * @param linenumber where in the code was the call to GNUNET_array_grow | ||
44 | * @return pointer to size bytes of memory | ||
45 | */ | ||
46 | void * | ||
47 | GNUNET_xmalloc_ (size_t size, const char *filename, int linenumber) | ||
48 | { | ||
49 | /* As a security precaution, we generally do not allow very large | ||
50 | allocations using the default 'GNUNET_malloc' macro */ | ||
51 | GNUNET_assert_at (size <= GNUNET_MAX_GNUNET_MALLOC_CHECKED, filename, | ||
52 | linenumber); | ||
53 | return GNUNET_xmalloc_unchecked_ (size, filename, linenumber); | ||
54 | } | ||
55 | |||
56 | void * | ||
57 | GNUNET_xmalloc_unchecked_ (size_t size, const char *filename, int linenumber) | ||
58 | { | ||
59 | void *result; | ||
60 | |||
61 | GNUNET_assert_at (size < INT_MAX, filename, linenumber); | ||
62 | result = malloc (size); | ||
63 | if (result == NULL) | ||
64 | { | ||
65 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "malloc"); | ||
66 | abort (); | ||
67 | } | ||
68 | memset (result, 0, size); | ||
69 | return result; | ||
70 | } | ||
71 | |||
72 | /** | ||
73 | * Reallocate memory. Checks the return value, aborts if no more | ||
74 | * memory is available. | ||
75 | * | ||
76 | * @ptr the pointer to reallocate | ||
77 | * @param size how many bytes of memory to allocate, do NOT use | ||
78 | * this function (or GNUNET_malloc) to allocate more than several MB | ||
79 | * of memory | ||
80 | * @param filename where in the code was the call to GNUNET_realloc | ||
81 | * @param linenumber where in the code was the call to GNUNET_realloc | ||
82 | * @return pointer to size bytes of memory | ||
83 | */ | ||
84 | void * | ||
85 | GNUNET_xrealloc_ (void *ptr, | ||
86 | const size_t n, const char *filename, int linenumber) | ||
87 | { | ||
88 | ptr = realloc (ptr, n); | ||
89 | if (!ptr) | ||
90 | { | ||
91 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "realloc"); | ||
92 | abort (); | ||
93 | } | ||
94 | return ptr; | ||
95 | } | ||
96 | |||
97 | /** | ||
98 | * Free memory. Merely a wrapper for the case that we | ||
99 | * want to keep track of allocations. | ||
100 | * | ||
101 | * @param ptr the pointer to free | ||
102 | * @param filename where in the code was the call to GNUNET_array_grow | ||
103 | * @param linenumber where in the code was the call to GNUNET_array_grow | ||
104 | */ | ||
105 | void | ||
106 | GNUNET_xfree_ (void *ptr, const char *filename, int linenumber) | ||
107 | { | ||
108 | GNUNET_assert_at (ptr != NULL, filename, linenumber); | ||
109 | free (ptr); | ||
110 | } | ||
111 | |||
112 | /** | ||
113 | * Dup a string (same semantics as strdup). | ||
114 | * | ||
115 | * @param str the string to dup | ||
116 | * @param filename where in the code was the call to GNUNET_array_grow | ||
117 | * @param linenumber where in the code was the call to GNUNET_array_grow | ||
118 | * @return strdup(str) | ||
119 | */ | ||
120 | char * | ||
121 | GNUNET_xstrdup_ (const char *str, const char *filename, int linenumber) | ||
122 | { | ||
123 | char *res; | ||
124 | |||
125 | GNUNET_assert_at (str != NULL, filename, linenumber); | ||
126 | res = GNUNET_xmalloc_ (strlen (str) + 1, filename, linenumber); | ||
127 | memcpy (res, str, strlen (str) + 1); | ||
128 | return res; | ||
129 | } | ||
130 | |||
131 | /** | ||
132 | * Grow an array. Grows old by (*oldCount-newCount)*elementSize bytes | ||
133 | * and sets *oldCount to newCount. | ||
134 | * | ||
135 | * @param old address of the pointer to the array | ||
136 | * *old may be NULL | ||
137 | * @param elementSize the size of the elements of the array | ||
138 | * @param oldCount address of the number of elements in the *old array | ||
139 | * @param newCount number of elements in the new array, may be 0 | ||
140 | * @param filename where in the code was the call to GNUNET_array_grow | ||
141 | * @param linenumber where in the code was the call to GNUNET_array_grow | ||
142 | */ | ||
143 | void | ||
144 | GNUNET_xgrow_ (void **old, | ||
145 | size_t elementSize, | ||
146 | unsigned int *oldCount, | ||
147 | unsigned int newCount, const char *filename, int linenumber) | ||
148 | { | ||
149 | void *tmp; | ||
150 | size_t size; | ||
151 | |||
152 | GNUNET_assert_at (INT_MAX / elementSize > newCount, filename, linenumber); | ||
153 | size = newCount * elementSize; | ||
154 | if (size == 0) | ||
155 | { | ||
156 | tmp = NULL; | ||
157 | } | ||
158 | else | ||
159 | { | ||
160 | tmp = GNUNET_xmalloc_ (size, filename, linenumber); | ||
161 | memset (tmp, 0, size); /* client code should not rely on this, though... */ | ||
162 | if (*oldCount > newCount) | ||
163 | *oldCount = newCount; /* shrink is also allowed! */ | ||
164 | memcpy (tmp, *old, elementSize * (*oldCount)); | ||
165 | } | ||
166 | |||
167 | if (*old != NULL) | ||
168 | { | ||
169 | GNUNET_xfree_ (*old, filename, linenumber); | ||
170 | } | ||
171 | *old = tmp; | ||
172 | *oldCount = newCount; | ||
173 | } | ||
174 | |||
175 | |||
176 | int | ||
177 | GNUNET_asprintf (char **buf, const char *format, ...) | ||
178 | { | ||
179 | int ret; | ||
180 | va_list args; | ||
181 | |||
182 | va_start (args, format); | ||
183 | ret = VSNPRINTF (NULL, 0, format, args); | ||
184 | va_end (args); | ||
185 | *buf = GNUNET_malloc (ret + 1); | ||
186 | va_start (args, format); | ||
187 | ret = VSPRINTF (*buf, format, args); | ||
188 | va_end (args); | ||
189 | return ret; | ||
190 | } | ||
191 | |||
192 | int | ||
193 | GNUNET_snprintf (char *buf, size_t size, const char *format, ...) | ||
194 | { | ||
195 | int ret; | ||
196 | va_list args; | ||
197 | |||
198 | va_start (args, format); | ||
199 | ret = VSNPRINTF (buf, size, format, args); | ||
200 | va_end (args); | ||
201 | GNUNET_assert (ret <= size); | ||
202 | return ret; | ||
203 | } | ||
204 | |||
205 | |||
206 | /* end of common_allocation.c */ | ||