[0] https://gitlab.com/sifoo/snigl/blob/master/src/snigl/pool.h
[0] https://gitlab.com/sifoo/snigl/blob/master/src/snigl/pool.h
There is exactly zero difference from the operating system's perspective between freeing and not freeing the memory before program termination (except that one might have a higher peak memory usage).
The classic implementations of several standard Unix utilities deliberately never deallocated memory for performance reasons. If there was a problem with this practice, I would expect Bell Labs--of all places--to know not to do it.
Close, but not quite: in case of larger allocations, malloc() tends to use mmap( , , , | MAP_ANON) rather than brk() to request memory from the OS. For example, the glibc's malloc() uses mmap() when requested size exceeds MMAP_THRESHOLD, which is 128kB by default.
The mmap() approach gives large, continuous memory blocks that can also be easily free()'d via munmap() with little to no bookkeeping needed[1] - not being subject to the same fragmentation woes as memory allocated via brk() - as long as your address space is significantly larger than allocated memory.
That aside, I fully agree with the author of 9cc.
[1] in fact a simplistic libc memory allocator could directly wrap malloc() around mmap(), free() around munmap() and realloc() around mrealloc(), leveraging the in-kernel allocator at the cost of one syscall with at least two context switches at each call - i.e., slowww
If that doesn't fit neatly into your delusions it's really not my problem.