Usage of return value of _replace(assigning to dest) should work fine
Code:
int main()
{
char search[] = "Hi";
char replace[] = "Bye";
char str[] = "HelloHiHelloHi";
char *dest;
dest = _replace(str, search, replace, dest);
printf("replaced string is %s\n", dest);
return 0;
}
Output of this is - HelloByeHelloBye. But if we directly use dest like below
Code:
_replace(str, search, replace, dest);
printf("replaced string is %s\n", dest);
this may result into segmentation fault. This is because "dest" is not initialized(not pointing) to any memory location. "dest" is passed as a value(not by pointer) and _replace function allocates memory locally and initializes it to local pointer(ostr - and this does not reflect to dest). On exit of _replace function ostr variable is deallocated and we lost the reference to allocated memory. So, it could result into memory leak too.

We should be careful when allocating memory in called function. It is good idea to always return the pointer to allocated memory. So the _replace specification becomes

Code:
char* _replace(char* source_str,char* search_str,char* replace_str) // last argument is removed
But still if the last argument is required then pass address of "dest" to _replace. Then specification becomes

Code:
char* _replace(char* source_str,char* search_str,char* replace_str,char** ostr) // type of ostr is changed to char**
and _replace function has to be updated accordingly(just replace ostr usage with *ostr) so that the change in ostr reflects to "dest" in callee function.

Hope this may help you.