Malloc is generic and good. Many small allocations will work but they will slow your application down.
It may be better if the application allocates a large chunk of heap and maintains it by itself. It knows best what kind of allocations will happen. Try to avoid frequent small allocations via malloc.
Do not give memory back just to allocate it a few milliseconds later again. Keep your own memory pool and REUSE memory as much as possible. Caching and pooling is the name of the game for successful applications.
In languages without garbage collection: Define your own memory management policy and design a coding standard with function names that make it clear when somebody takes over responsibility for a piece of memory.
char* value = getSomething(); // does the function expect the caller to call free? // is the memory area a constant and the program // will crash if free(value) is called? // if value will be a parameter to another call, who // will take over responsibility for free-ing it?