free() does not call sbrk()

Jeff Johnston
Tue Sep 15 20:43:00 GMT 2009

On 15/09/09 06:54 AM, Martin Walter wrote:
> Hello!
> I am just testing my port of the newlib-1.17.0 for our architecture
> and came across the following issue:
> (1) the newlib libc documentation says that free() invokes sbrk() with
> a negative incrementer argument, but a simple debug trace reveals that
> sbrk() is actually never called by free().
> (2) when malloc()'ing and free()'ing chunks of memory in a loop it
> seems that memory is actually never free()'d, which might be due to
> (1). instead, the heap keeps on growing.
> I guess this is not the intended behavior. Any ideas? Thank you!
> Cheers,
> Martin

For starters, you can only give back the end of the last block you took.
You'll notice that malloc_trim does this using MORECORE(-extra).

The documentation does not guarantee "free" will call _sbrk_r with a 
negative value.  Free gives back storage to the memory storage pool.

> When you no longer need an object originally allocated by <<malloc>>
> or <<realloc>> (or the related function <<calloc>>), return it to the
> memory storage pool by calling <<free>> with the address of the object
> as the argument.  You can also use <<realloc>> for this purpose by
> calling it with <<0>> as the <[nbytes]> argument.

The comment about sbrk is later on:

>  <<_sbrk_r>> is called with a positive
> value to allocate more space, and with a negative value to release
> previously allocated space if it is no longer required.

The current malloc design chosen tries to balance speed and maximizing 
memory usage (i.e. minimizing fragmentation).  It manages the storage 
internally.  For example, it has a pool of small blocks (bin) that it 
reuses over and over again for small requests.  This storage is not 
given back when you free.

For a discussion on the design see:
which is referenced in libc/stdlib/mallocr.c

My simple test of mallocing a block of 4000 and freeing it back again in 
an infinite loop results in the same pointer being given back each time 
and no increment in memory usage.  I do not know why you are not seeing 
similar behavior for your test.  Is there something else in your loop 
other than malloc/free? (mine has a printf as well)

-- Jeff J.

More information about the Newlib mailing list