11#include < stdlib.h>
22
3+ #include < assert.h>
34#include < stdalign.h>
45#include < stdbool.h>
56#include < stdint.h>
67#include < stdio.h>
78#include < string.h>
89
9- #define MALLOC_TRACE 0
10-
10+ #ifndef NDEBUG
1111#define TRACE (fmt, ...) \
12- if (MALLOC_TRACE) \
1312 printf (fmt __VA_OPT__ (, ) __VA_ARGS__)
13+ #else
14+ #define TRACE (fmt, ...) (void )0
15+ #endif
1416
1517extern char __heap_start;
1618extern char __heap_default_limit;
@@ -40,6 +42,8 @@ class Chunk {
4042
4143 // Slow; prefer prev_free where possible.
4244 bool free () const ;
45+
46+ void set_free (bool free);
4347};
4448
4549class FreeChunk : public Chunk {
@@ -102,6 +106,14 @@ bool Chunk::free() const {
102106 return n ? n->prev_free : last_free;
103107}
104108
109+ void Chunk::set_free (bool free) {
110+ Chunk *n = next ();
111+ if (n)
112+ n->prev_free = free;
113+ else
114+ last_free = free;
115+ }
116+
105117// Remove a free chunk from the free list.
106118void FreeChunk::remove () {
107119 TRACE (" FreeChunk(%p)::remove\n " , this );
@@ -187,11 +199,7 @@ void *allocate_free_chunk(FreeChunk *free_chunk, size_t size) {
187199 chunk->set_size (size);
188200 }
189201
190- Chunk *next = chunk->next ();
191- if (next)
192- next->prev_free = false ;
193- else
194- last_free = false ;
202+ chunk->set_free (false );
195203
196204 TRACE (" Allocated size: %u\n " , size);
197205
@@ -296,7 +304,7 @@ void *aligned_alloc(size_t alignment, size_t size) {
296304 if (!size)
297305 return nullptr ;
298306
299- // The region before the aligned chunk needs to be large enough to fit a free
307+ // The region before the aligned chunk needs to be large enough to fit a freereallocated chunk should not be free");
300308 // chunk.
301309 if (__builtin_add_overflow (size, MIN_CHUNK_SIZE, &size))
302310 return nullptr ;
@@ -462,11 +470,7 @@ void *realloc(void *ptr, size_t size) {
462470 FreeChunk *after = FreeChunk::insert (chunk->end (), shrink);
463471 TRACE (" Allocated remainder %p of size %u\n " , after, after->size ());
464472 after->prev_free = false ;
465- Chunk *after_next = after->next ();
466- if (after_next)
467- after_next->prev_free = true ;
468- else
469- last_free = true ;
473+ after->set_free (true );
470474 return ptr;
471475 }
472476
@@ -493,6 +497,7 @@ void *realloc(void *ptr, size_t size) {
493497 FreeChunk::insert (chunk->end (), next_size - grow)->prev_free = false ;
494498 }
495499
500+ assert (!chunk->free () && " newly reallocated chunk should not be free" );
496501 return ptr;
497502 }
498503 }
0 commit comments