When a process calls free() it does not return the memory immediately back to system, instead it returns it back to the heap owned by that process. The heap either uses anonymous memory mapping for large chunks or sbrk() to shrink or grow the heap. Memory from the heap is returned back to the system when it is unmap'd or the heap shrinks with sbrk(). At this point pages can be re-used by other processes and when they are re-used they are always zero'd before the process can access it. 
memory allocations such as malloc don't zero memory when it is free'd back to the heap because of performance issues. Normally, the best practice for sensitive data is to be zero'd before it free'ing it. However, I guess you want to enforce this police for all memory being free'd during a processes' life time. glibc 2.4 and upwards has a MALLOC_PERTURB_ environment option that when set to non-zero value will initialize the memory to the compliment of the value when the memory is allocated and when it is released with free(). The downside to this is that it may trigger bugs in code that erroneously rely on the memory to be normally initialized to zero on allocation.
To use MALLOC_PERTURB_, e.g. to set it to a random value..
export MALLOC_PERTURB_=$(($RANDOM % 255 + 1))
and run your code.
 Well almost. mmap() using MAP_UNINITIALIZED and a kernel configured with CONFIG_MMAP_ALLOW_UNINITIALIZED allows non-zeroing of memory, but this is never allowed on Ubuntu.