@@ -99,14 +99,14 @@ arena_block_t *arena_block_create(int capacity)
9999 arena_block_t * block = malloc (sizeof (arena_block_t ));
100100
101101 if (!block ) {
102- printf ("Failed to allocate memory for arena block\n" );
102+ printf ("Failed to allocate memory for arena block structure \n" );
103103 exit (1 );
104104 }
105105
106- block -> memory = calloc (capacity , sizeof (char ));
106+ block -> memory = malloc (capacity * sizeof (char ));
107107
108108 if (!block -> memory ) {
109- printf ("Failed to allocate memory for arena block\n" );
109+ printf ("Failed to allocate memory for arena block buffer \n" );
110110 free (block );
111111 exit (1 );
112112 }
@@ -117,6 +117,16 @@ arena_block_t *arena_block_create(int capacity)
117117 return block ;
118118}
119119
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+
120130/**
121131 * arena_init() - Initializes the given arena with initial capacity.
122132 * @initial_capacity: The initial capacity of the arena. Must be positive.
@@ -126,6 +136,10 @@ arena_block_t *arena_block_create(int capacity)
126136arena_t * arena_init (int initial_capacity )
127137{
128138 arena_t * arena = malloc (sizeof (arena_t ));
139+ if (!arena ) {
140+ printf ("Failed to allocate memory for arena structure\n" );
141+ exit (1 );
142+ }
129143 arena -> head = arena_block_create (initial_capacity );
130144 return arena ;
131145}
@@ -141,47 +155,93 @@ arena_t *arena_init(int initial_capacity)
141155 */
142156void * arena_alloc (arena_t * arena , int size )
143157{
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 );
156161 }
157162
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 );
163165
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+ }
166174
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 ;
170177 return ptr ;
171178}
172179
173180/**
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.
176222 */
177- void arena_reset (arena_t * arena )
223+ char * arena_strdup (arena_t * arena , char * str )
178224{
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+ }
180231
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 );
185245}
186246
187247/**
@@ -194,8 +254,7 @@ void arena_free(arena_t *arena)
194254
195255 while (block ) {
196256 next = block -> next ;
197- free (block -> memory );
198- free (block );
257+ arena_block_free (block );
199258 block = next ;
200259 }
201260
0 commit comments