Use the argv where they lay (in the heap already, part of environment), just assign the char* to a identifying variable, and do not make a copy. If you must copy, malloc for the strlen+1 or go to C++ RWCString, JAVA. You just need cha* for str1 and str2, a dynamically sized char[]'s for last good and trial of strlen(str1)+strlen(str2)+1. The test is memcmp(str1, trial, strlen(str1)). When you trim str1 to nothing or it mismatches, the last good is it.
You do not need to free() when you exit(), exit() does it all: fflush(), fclose(), close() (socket disconnect, TCP DB session rollback) and virtual free(). All memory for a process is released on exit(). Memory leaks are a problem for daemons, which almost never exit(), and internal processing loops.
You cannot copy a char[] with = here: str3=strmerg(str1, str2); You destroyed the value of str3 placed there by malloc. the only clue it can use to free(), a memory leak since you did not save that value for free(). Subroutines that return char[] can either use a static but that is a vlaue destroyed at the next call, not MT-Safe, or malloc a new buffer to return, whose free() falls on the caller, or more usually the caller should send it in as an additional arg, and if the size is not explicit, with a size, like with the improvement of sprintf() to snprintf(), localtime() to localtime_r():
https://www.unix.com/man-page/opensolaris/0/snprintf/ https://www.unix.com/man-page/opensolaris/0/localtime_r/