@@ -529,13 +529,27 @@ int fputc(int c, FILE *stream)
529529/* Non-portable: Assume page size is 4KiB */
530530#define PAGESIZE 4096
531531
532+ #define CHUNK_SIZE_FREED_MASK 1
533+ #define CHUNK_SIZE_SZ_MASK 0xFFFFFFFE
534+ #define CHUNK_GET_SIZE (size ) (size & CHUNK_SIZE_SZ_MASK)
535+ #define IS_CHUNK_GET_FREED (size ) (size & CHUNK_SIZE_FREED_MASK)
536+
532537typedef struct chunk {
533538 struct chunk * next ;
534539 struct chunk * prev ;
535540 int size ;
536- void * ptr ;
537541} chunk_t ;
538542
543+ void chunk_set_freed (chunk_t * chunk )
544+ {
545+ chunk -> size |= CHUNK_SIZE_FREED_MASK ;
546+ }
547+
548+ void chunk_clear_freed (chunk_t * chunk )
549+ {
550+ chunk -> size &= CHUNK_SIZE_SZ_MASK ;
551+ }
552+
539553int __align_up (int size )
540554{
541555 int mask = PAGESIZE - 1 ;
@@ -562,7 +576,6 @@ void *malloc(int size)
562576 __alloc_tail = tmp ;
563577 __alloc_head -> next = NULL ;
564578 __alloc_head -> prev = NULL ;
565- __alloc_head -> ptr = NULL ;
566579 __alloc_head -> size = 0 ;
567580 }
568581
@@ -573,7 +586,6 @@ void *malloc(int size)
573586 __freelist_head = tmp ;
574587 __freelist_head -> next = NULL ;
575588 __freelist_head -> prev = NULL ;
576- __freelist_head -> ptr = NULL ;
577589 __freelist_head -> size = -1 ;
578590 }
579591
@@ -591,15 +603,16 @@ void *malloc(int size)
591603 int bsize = 0 ;
592604
593605 for (chunk_t * fh = __freelist_head ; fh -> next ; fh = fh -> next ) {
594- if (fh -> size >= size && !best_fit_chunk ) {
606+ int fh_size = CHUNK_GET_SIZE (fh -> size );
607+ if (fh_size >= size && !best_fit_chunk ) {
595608 /* first time setting fh as best_fit_chunk */
596609 best_fit_chunk = fh ;
597- bsize = fh -> size ;
598- } else if ((fh -> size >= size ) && best_fit_chunk &&
599- (fh -> size < bsize )) {
610+ bsize = fh_size ;
611+ } else if ((fh_size >= size ) && best_fit_chunk &&
612+ (fh_size < bsize )) {
600613 /* If there is a smaller chunk available, replace it. */
601614 best_fit_chunk = fh ;
602- bsize = fh -> size ;
615+ bsize = fh_size ;
603616 }
604617 }
605618
@@ -633,9 +646,9 @@ void *malloc(int size)
633646 __alloc_tail = allocated ;
634647 __alloc_tail -> next = NULL ;
635648 __alloc_tail -> size = allocated -> size ;
636- int offset = sizeof ( chunk_t ) - 4 ;
637- __alloc_tail -> ptr = __alloc_tail + offset ;
638- return __alloc_tail -> ptr ;
649+ chunk_clear_freed ( __alloc_tail ) ;
650+ void * ptr = __alloc_tail + 1 ;
651+ return ptr ;
639652}
640653
641654void * calloc (int n , int size )
@@ -660,14 +673,16 @@ int __free_all()
660673
661674 chunk_t * cur = __freelist_head ;
662675 chunk_t * rel ;
676+ int size ;
663677
664678 /* release freelist */
665679 while (cur -> next ) {
666680 rel = cur ;
667681 cur = cur -> next ;
668682 rel -> next = NULL ;
669683 rel -> prev = NULL ;
670- __rfree (rel , rel -> size );
684+ size = CHUNK_GET_SIZE (rel -> size );
685+ __rfree (rel , size );
671686 }
672687
673688 if (__alloc_head -> next ) {
@@ -678,7 +693,8 @@ int __free_all()
678693 cur = cur -> next ;
679694 rel -> next = NULL ;
680695 rel -> prev = NULL ;
681- __rfree (rel , rel -> size );
696+ size = CHUNK_GET_SIZE (rel -> size );
697+ __rfree (rel , size );
682698 }
683699 }
684700 return 0 ;
@@ -689,14 +705,11 @@ void free(void *ptr)
689705 if (!ptr )
690706 return ;
691707
692- /* FIXME: it takes long time to search in chuncks */
693- chunk_t * cur = __alloc_head ;
694- while (cur -> ptr != ptr ) {
695- cur = cur -> next ;
696- if (!cur ) {
697- printf ("free(): double free detected\n" );
698- abort ();
699- }
708+ char * __ptr = ptr ;
709+ chunk_t * cur = __ptr - sizeof (chunk_t );
710+ if (IS_CHUNK_GET_FREED (cur -> size )) {
711+ printf ("free(): double free detected\n" );
712+ abort ();
700713 }
701714
702715 chunk_t * prev ;
@@ -717,6 +730,7 @@ void free(void *ptr)
717730 /* Insert head in __freelist_head */
718731 cur -> next = __freelist_head ;
719732 cur -> prev = NULL ;
733+ chunk_set_freed (cur );
720734 __freelist_head -> prev = cur ;
721735 __freelist_head = cur ;
722736}
0 commit comments