libc malloc does not return memory to the kernel instead it uses a local
pool. Thats standard for almost all Unix libc malloc implementations as
very few applications have the property you describe and the malloc heap
tends to have freed holes in it not a single giant free chunk.
You can use mmap() to get a block of memory you can hand back if you wish