You can call free in the final function for that allocated pointer, but it's not a good practice. Good practice is to call free function inside the function that owns the main pointer to the allocated memory (that may not be the function that allocates memory).
Here's an example:
void func()
{
void* ptr = malloc(...); // ptr variable declared and initialized here.
func2(ptr);
func3(ptr);
func4(ptr);
free(ptr); // Free memory in function where ptr is declared.
}
Or, if malloc and free are incapsulated in higher-level functions:
void func()
{
void* ptr = allocateObject(...); // This function calls "malloc".
func2(ptr);
func3(ptr);
func4(ptr);
freeObject(ptr); // This function calls "free".
}
Consider also that C free function free dynamic allocated memory but don't change ptr variable value.
So if you're experiencing memory leaks a good practice is to set pointer variables to NULL after calling free. This way debugging the code you may immediately know if memory is allocated (ptr != NULL) or no (ptr == NULL)
if(ptr != NULL)
{
free(ptr);
ptr = NULL;
}