@@ -265,6 +265,16 @@ static inline union heap_entry *heap_prev_block(union heap_entry *current,
265265 return block ;
266266}
267267
268+ static inline union heap_entry *
269+ heap_block_from_usermemory (void * ptr , int verify_signature ) {
270+ union heap_entry * block = ptr - HEAP_HEADER_SIZE ;
271+ if (verify_signature ) {
272+ heap_assert (block -> content .signature == HEAP_ENTRY_SIGNATURE ,
273+ "heap_block_from_usermemory, invalid signature" );
274+ }
275+ return block ;
276+ }
277+
268278static inline union heap_entry * heap_push_back (union heap_entry * olast ,
269279 size_t new_size ) {
270280 heap_assert (olast -> content .state == HEAP_BLOCK_LAST ,
@@ -389,6 +399,10 @@ static inline union heap_entry *heap_get_free_block(size_t new_size) {
389399
390400void * malloc (size_t size ) {
391401 heap_may_init ();
402+ if (size == 0 ) {
403+ // do nothing
404+ return NULL ;
405+ }
392406 // allocates in chunk of 4
393407 size = ((size + 3 ) >> 2 ) << 2 ;
394408 // allocate header
@@ -402,13 +416,13 @@ void *malloc(size_t size) {
402416}
403417
404418void free (void * ptr ) {
405- if (ptr == NULL )
406- return ;
407419 heap_may_init ();
420+ if (ptr == NULL ) {
421+ // do nothing
422+ return ;
423+ }
408424
409- // current version of malloc is non-optimal and doesn't
410- // do any free operation.
411- union heap_entry * header = ptr - HEAP_HEADER_SIZE ;
425+ union heap_entry * header = heap_block_from_usermemory (ptr , 1 );
412426 if (header -> content .state != HEAP_BLOCK_ALLOCATED ) {
413427 // trying to free unallocated memory
414428 return ;
@@ -420,3 +434,28 @@ void free(void *ptr) {
420434 heap_freeblocks_merge (header );
421435#endif
422436}
437+
438+ void * realloc (void * ptr , size_t size ) {
439+ heap_may_init ();
440+ if (ptr == NULL ) {
441+ return malloc (size );
442+ }
443+
444+ union heap_entry * header = heap_block_from_usermemory (ptr , 1 );
445+ size_t old_size = header -> content .size - HEAP_HEADER_SIZE ;
446+
447+ if (old_size == size ) {
448+ // no need to allocate or free memory
449+ return ptr ;
450+ }
451+
452+ // allocate memory for new data size
453+ void * newdata = malloc (size );
454+ // copy data
455+ size_t copy_size = min (size , old_size );
456+ memcpy (newdata , ptr , copy_size );
457+ // free old data
458+ free (ptr );
459+
460+ return newdata ;
461+ }
0 commit comments