@@ -578,6 +578,10 @@ int fputc(int c, FILE *stream)
578
578
#define CHUNK_GET_SIZE (size ) (size & CHUNK_SIZE_SZ_MASK)
579
579
#define IS_CHUNK_GET_FREED (size ) (size & CHUNK_SIZE_FREED_MASK)
580
580
581
+ /* Minimum alignment for all memory allocations. */
582
+ #define MIN_ALIGNMENT 8
583
+ #define ALIGN_UP (val , align ) (((val) + (align) - 1) & ~((align) - 1))
584
+
581
585
typedef struct chunk {
582
586
struct chunk * next , * prev ;
583
587
int size ;
@@ -595,8 +599,7 @@ void chunk_clear_freed(chunk_t *chunk)
595
599
596
600
int __align_up (int size )
597
601
{
598
- int mask = PAGESIZE - 1 ;
599
- return ((size - 1 ) | mask ) + 1 ;
602
+ return ALIGN_UP (size , PAGESIZE );
600
603
}
601
604
602
605
chunk_t * __alloc_head ;
@@ -611,6 +614,9 @@ void *malloc(int size)
611
614
int flags = 34 ; /* MAP_PRIVATE (0x02) | MAP_ANONYMOUS (0x20) */
612
615
int prot = 3 ; /* PROT_READ (0x01) | PROT_WRITE (0x02) */
613
616
617
+ /* Align size to MIN_ALIGNMENT */
618
+ size = ALIGN_UP (size , MIN_ALIGNMENT );
619
+
614
620
if (!__alloc_head ) {
615
621
chunk_t * tmp =
616
622
__syscall (__syscall_mmap2 , NULL , __align_up (sizeof (chunk_t )), prot ,
@@ -632,45 +638,31 @@ void *malloc(int size)
632
638
__freelist_head -> size = -1 ;
633
639
}
634
640
635
- /* to search the best chunk */
641
+ /* Search for the best fit chunk in the free list */
636
642
chunk_t * best_fit_chunk = NULL ;
637
643
chunk_t * allocated ;
644
+ int best_size = 0 ;
638
645
639
646
if (!__freelist_head -> next ) {
640
- /* If no more chunks in the free chunk list, allocate best_fit_chunk
641
- * as NULL.
642
- */
643
- allocated = best_fit_chunk ;
647
+ allocated = NULL ;
644
648
} else {
645
- /* record the size of the chunk */
646
- int bsize = 0 ;
647
-
648
649
for (chunk_t * fh = __freelist_head ; fh -> next ; fh = fh -> next ) {
649
650
int fh_size = CHUNK_GET_SIZE (fh -> size );
650
- if (fh_size >= size && !best_fit_chunk ) {
651
- /* first time setting fh as best_fit_chunk */
651
+ if (fh_size >= size && (!best_fit_chunk || fh_size < best_size )) {
652
652
best_fit_chunk = fh ;
653
- bsize = fh_size ;
654
- } else if ((fh_size >= size ) && best_fit_chunk &&
655
- (fh_size < bsize )) {
656
- /* If there is a smaller chunk available, replace it. */
657
- best_fit_chunk = fh ;
658
- bsize = fh_size ;
653
+ best_size = fh_size ;
659
654
}
660
655
}
661
656
662
- /* a suitable chunk has been found */
663
657
if (best_fit_chunk ) {
664
- /* remove the chunk from the freelist */
658
+ /* Remove from freelist */
665
659
if (best_fit_chunk -> prev ) {
666
- chunk_t * tmp = best_fit_chunk -> prev ;
667
- tmp -> next = best_fit_chunk -> next ;
668
- } else
660
+ best_fit_chunk -> prev -> next = best_fit_chunk -> next ;
661
+ } else {
669
662
__freelist_head = best_fit_chunk -> next ;
670
-
663
+ }
671
664
if (best_fit_chunk -> next ) {
672
- chunk_t * tmp = best_fit_chunk -> next ;
673
- tmp -> prev = best_fit_chunk -> prev ;
665
+ best_fit_chunk -> next -> prev = best_fit_chunk -> prev ;
674
666
}
675
667
}
676
668
allocated = best_fit_chunk ;
@@ -683,19 +675,26 @@ void *malloc(int size)
683
675
allocated -> size = __align_up (sizeof (chunk_t ) + size );
684
676
}
685
677
678
+ /* Add to allocation list */
686
679
__alloc_tail -> next = allocated ;
687
680
allocated -> prev = __alloc_tail ;
688
-
689
681
__alloc_tail = allocated ;
690
682
__alloc_tail -> next = NULL ;
691
683
__alloc_tail -> size = allocated -> size ;
692
684
chunk_clear_freed (__alloc_tail );
685
+
693
686
void * ptr = __alloc_tail + 1 ;
694
687
return ptr ;
695
688
}
696
689
697
690
void * calloc (int n , int size )
698
691
{
692
+ /* Check for overflow before multiplication */
693
+ if (!n || !size )
694
+ return NULL ;
695
+ if (size != 0 && n > INT_MAX / size )
696
+ return NULL ; /* Overflow protection */
697
+
699
698
int total = n * size ;
700
699
char * p = malloc (total );
701
700
@@ -722,7 +721,7 @@ int __free_all(void)
722
721
int size ;
723
722
724
723
/* release freelist */
725
- while (cur -> next ) {
724
+ while (cur && cur -> next ) {
726
725
rel = cur ;
727
726
cur = cur -> next ;
728
727
rel -> next = NULL ;
@@ -731,7 +730,7 @@ int __free_all(void)
731
730
__rfree (rel , size );
732
731
}
733
732
734
- if (__alloc_head -> next ) {
733
+ if (__alloc_head && __alloc_head -> next ) {
735
734
cur = __alloc_head -> next ;
736
735
/* release chunks which not be free */
737
736
while (cur ) {
@@ -758,17 +757,18 @@ void free(void *ptr)
758
757
abort ();
759
758
}
760
759
761
- chunk_t * prev ;
760
+ chunk_t * prev = NULL ;
762
761
if (cur -> prev ) {
763
762
prev = cur -> prev ;
764
763
prev -> next = cur -> next ;
765
- } else
764
+ } else {
766
765
__alloc_head = cur -> next ;
766
+ }
767
767
768
768
if (cur -> next ) {
769
769
chunk_t * next = cur -> next ;
770
770
next -> prev = cur -> prev ;
771
- } else {
771
+ } else if ( prev ) {
772
772
prev -> next = NULL ;
773
773
__alloc_tail = prev ;
774
774
}
@@ -777,6 +777,7 @@ void free(void *ptr)
777
777
cur -> next = __freelist_head ;
778
778
cur -> prev = NULL ;
779
779
chunk_set_freed (cur );
780
- __freelist_head -> prev = cur ;
780
+ if (__freelist_head )
781
+ __freelist_head -> prev = cur ;
781
782
__freelist_head = cur ;
782
783
}
0 commit comments