How does dynamic memory allocation (malloc, calloc, realloc) work under the hood, and what are the risks of memory fragmentation in embedded systems?