Being able to "handle" fragmentation is a rather steep requirement. If you mean that the manager must be able to de-fragment the memory, this means it can't have the standard C malloc()
API. You need an indirect API, where memory allocations are referenced not by actual directly dereferencable addresses, but something more abstract.
This is because your memory manager must have the ability to move allocated memory blocks around during defragmentation, and it can't do that if the application is holding direct absolute pointers into allocated memory.
Of course, forcing the application to be indirect in its use of memory means many common C idioms and APIs break, since the expectation to use pointers freely is common in C.