@@ -99,14 +99,14 @@ arena_block_t *arena_block_create(int capacity)
99
99
arena_block_t * block = malloc (sizeof (arena_block_t ));
100
100
101
101
if (!block ) {
102
- printf ("Failed to allocate memory for arena block\n" );
102
+ printf ("Failed to allocate memory for arena block structure \n" );
103
103
exit (1 );
104
104
}
105
105
106
- block -> memory = calloc (capacity , sizeof (char ));
106
+ block -> memory = malloc (capacity * sizeof (char ));
107
107
108
108
if (!block -> memory ) {
109
- printf ("Failed to allocate memory for arena block\n" );
109
+ printf ("Failed to allocate memory for arena block buffer \n" );
110
110
free (block );
111
111
exit (1 );
112
112
}
@@ -117,6 +117,16 @@ arena_block_t *arena_block_create(int capacity)
117
117
return block ;
118
118
}
119
119
120
+ /**
121
+ * arena_block_free() - Free a single arena block and its memory buffer.
122
+ * @block: Pointer to the arena_block_t to free. Must not be NULL.
123
+ */
124
+ void arena_block_free (arena_block_t * block )
125
+ {
126
+ free (block -> memory );
127
+ free (block );
128
+ }
129
+
120
130
/**
121
131
* arena_init() - Initializes the given arena with initial capacity.
122
132
* @initial_capacity: The initial capacity of the arena. Must be positive.
@@ -126,6 +136,10 @@ arena_block_t *arena_block_create(int capacity)
126
136
arena_t * arena_init (int initial_capacity )
127
137
{
128
138
arena_t * arena = malloc (sizeof (arena_t ));
139
+ if (!arena ) {
140
+ printf ("Failed to allocate memory for arena structure\n" );
141
+ exit (1 );
142
+ }
129
143
arena -> head = arena_block_create (initial_capacity );
130
144
return arena ;
131
145
}
@@ -141,47 +155,93 @@ arena_t *arena_init(int initial_capacity)
141
155
*/
142
156
void * arena_alloc (arena_t * arena , int size )
143
157
{
144
- char * ptr ;
145
- arena_block_t * block = arena -> head ;
146
-
147
- while (block ) {
148
- if (block -> offset + size <= block -> capacity ) {
149
- ptr = block -> memory + block -> offset ;
150
- block -> offset += size ;
151
- return ptr ;
152
- }
153
- if (!block -> next )
154
- break ;
155
- block = block -> next ;
158
+ if (size <= 0 ) {
159
+ printf ("arena_alloc: size must be positive" );
160
+ exit (1 );
156
161
}
157
162
158
- /* If no space is available, create a new block
159
- * Allocate at least 256 KiB or the requested size
160
- */
161
- int new_capacity = size > DEFAULT_ARENA_SIZE ? size : DEFAULT_ARENA_SIZE ;
162
- arena_block_t * new_block = arena_block_create (new_capacity );
163
+ /* Align to 4 bytes */
164
+ size = (size + 4 - 1 ) & ~(4 - 1 );
163
165
164
- if (!new_block )
165
- return NULL ;
166
+ if (!arena -> head || arena -> head -> offset + size > arena -> head -> capacity ) {
167
+ /* Need a new block: choose capacity = max(DEFAULT_ARENA_SIZE, size) */
168
+ int new_capacity =
169
+ (size > DEFAULT_ARENA_SIZE ? size : DEFAULT_ARENA_SIZE );
170
+ arena_block_t * new_block = arena_block_create (new_capacity );
171
+ new_block -> next = arena -> head ;
172
+ arena -> head = new_block ;
173
+ }
166
174
167
- block -> next = new_block ;
168
- ptr = new_block -> memory + new_block -> offset ;
169
- new_block -> offset += size ;
175
+ void * ptr = arena -> head -> memory + arena -> head -> offset ;
176
+ arena -> head -> offset += size ;
170
177
return ptr ;
171
178
}
172
179
173
180
/**
174
- * arena_reset() - Resets the given arena by resetting all blocks' offset to 0.
175
- * @arena: The arena to reset. Must not be NULL.
181
+ * arena_realloc() - Reallocate a previously allocated region within the arena
182
+ * to a different size.
183
+ *
184
+ * If existing region is the most recent allocation in the current block
185
+ * and there is enough space to expand in place, simply extend the offset.
186
+ * Otherwise, allocate a new region of the requested size and copy the old data.
187
+ *
188
+ * @arena: Pointer to the arena. Must not be NULL.
189
+ * @oldptr: Pointer to the previously allocated memory in the arena.
190
+ * @oldsz: Original size (in bytes) of that allocation.
191
+ * @newsz: New desired size (in bytes).
192
+ *
193
+ * Return: Pointer to the reallocated (resized) memory region.
194
+ */
195
+ void * arena_realloc (arena_t * arena , char * oldptr , int oldsz , int newsz )
196
+ {
197
+ /* No need to grow; existing pointer is sufficient. */
198
+ if (newsz <= oldsz )
199
+ return oldptr ;
200
+
201
+ /* Check if oldptr is at the end of the current block's allocations */
202
+ if (oldptr + oldsz == arena -> head -> memory + arena -> head -> offset &&
203
+ arena -> head -> offset + (newsz - oldsz ) <= arena -> head -> capacity ) {
204
+ /* Grow in place */
205
+ arena -> head -> offset += (newsz - oldsz );
206
+ return oldptr ;
207
+ }
208
+
209
+ /* Otherwise, allocate new region and copy */
210
+ void * newptr = arena_alloc (arena , newsz );
211
+ memcpy (newptr , oldptr , oldsz );
212
+ return newptr ;
213
+ }
214
+
215
+ /**
216
+ * arena_strdup() - Duplicate a NUL-terminated string into the arena.
217
+ *
218
+ * @arena: a Pointer to the arena. Must not be NULL.
219
+ * @str: NUL-terminated input string to duplicate. Must not be NULL.
220
+ *
221
+ * Return: Pointer to the duplicated string stored in the arena.
176
222
*/
177
- void arena_reset (arena_t * arena )
223
+ char * arena_strdup (arena_t * arena , char * str )
178
224
{
179
- arena_block_t * block = arena -> head ;
225
+ int n = strlen (str );
226
+ char * dup = arena_alloc (arena , n + 1 );
227
+ memcpy (dup , str , n );
228
+ dup [n ] = '\0' ;
229
+ return dup ;
230
+ }
180
231
181
- while (block ) {
182
- block -> offset = 0 ;
183
- block = block -> next ;
184
- }
232
+ /**
233
+ * arena_memdup() - Duplicate a block of memory into the arena.
234
+ * Allocates size bytes within the arena and copies data from the input pointer.
235
+ *
236
+ * @arena: a Pointer to the arena. Must not be NULL.
237
+ * @data: data Pointer to the source memory. Must not be NULL.
238
+ * @size: size Number of bytes to copy. Must be non-negative.
239
+ *
240
+ * Return: The pointer to the duplicated memory stored in the arena.
241
+ */
242
+ void * arena_memdup (arena_t * arena , void * data , int size )
243
+ {
244
+ return memcpy (arena_alloc (arena , size ), data , size );
185
245
}
186
246
187
247
/**
@@ -194,8 +254,7 @@ void arena_free(arena_t *arena)
194
254
195
255
while (block ) {
196
256
next = block -> next ;
197
- free (block -> memory );
198
- free (block );
257
+ arena_block_free (block );
199
258
block = next ;
200
259
}
201
260
0 commit comments